John
John

Reputation: 694

How to add timePicker using fragment?

I have 4 timePicker in my app. The timePicker dialog will pop out when the user double click on the editText. But sometimes when I accidentally click more than two times, the app crashed and said that the fragment already added. How can I fix this? Insted of clicking the editText twice, I want the timePicker dialog shown by just one click on the editText.

public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.editTextTI1) {
            tp.setFlag(TimePick.FLAG_START_DATE);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTO1) {
            tp.setFlag(TimePick.FLAG_END_DATE);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTI2) {
            tp.setFlag(TimePick.FLAG_START_DATE1);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTO2) {
            tp.setFlag(TimePick.FLAG_END_DATE1);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTI3) {
            tp.setFlag(TimePick.FLAG_START_DATE2);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTO3) {
            tp.setFlag(TimePick.FLAG_END_DATE2);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTI4) {
            tp.setFlag(TimePick.FLAG_START_DATE3);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }
        if (id == R.id.editTextTO4) {
            tp.setFlag(TimePick.FLAG_END_DATE3);
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            tp.show(ft, "TimePicker");
        }

    }




    public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener {

        public static final int FLAG_START_DATE = 00;
        public static final int FLAG_END_DATE = 01;
        public static final int FLAG_START_DATE1 = 10;
        public static final int FLAG_END_DATE1 = 11;
        public static final int FLAG_START_DATE2 = 20;
        public static final int FLAG_END_DATE2 = 21;
        public static final int FLAG_START_DATE3 = 30;
        public static final int FLAG_END_DATE3 = 31;
        private int flag = 00;

        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {

            final Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);

            return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
        }

        public void setFlag(int i) {
            flag = i;
        }

        @Override
        public void onTimeSet(TimePicker view, int hourofDay, int minute) {

            if (flag == FLAG_START_DATE) {
                start.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                b = start.getText().toString();
            }
            if (flag == FLAG_END_DATE) {
                end.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                c = end.getText().toString();
            }
            if (flag == FLAG_START_DATE1) {
                start1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                d = start1.getText().toString();
            }
            if (flag == FLAG_END_DATE1) {
                end1.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                e1 = end1.getText().toString();
            }
            if (flag == FLAG_START_DATE2) {
                start2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                f = start2.getText().toString();
            }
            if (flag == FLAG_END_DATE2) {
                end2.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                g = end2.getText().toString();
            }
            if (flag == FLAG_START_DATE3) {
                start3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                h = start3.getText().toString();
            }
            if (flag == FLAG_END_DATE3) {
                end3.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
                i = end3.getText().toString();
            }

LogCat Error

10-15 12:53:17.113    7943-7943/com.example.project.project E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.project.project, PID: 7943
    java.lang.IllegalStateException: Fragment already added: TimePick{7c7eb96 #0 TimePicker}
            at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1219)
            at android.app.BackStackRecord.run(BackStackRecord.java:715)
            at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
            at android.app.FragmentManagerImpl$1.run(FragmentManager.java:482)
            at android.os.Handler.handleCallback(Handler.java:739)
            at android.os.Handler.dispatchMessage(Handler.java:95)
            at android.os.Looper.loop(Looper.java:148)

Upvotes: 5

Views: 2145

Answers (2)

Beloo
Beloo

Reputation: 9925

Your code is so hardcoded and not easy to extend, which could lead to many bugs in future. You should encapsulate general logic as max as you can, so in current case:

 public void onClick(View v) {
    EditText editText = (EditText) v;
    if (tp==null || !tp.isAdded()){
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        tp = new TimePick(editText);
        tp.show(ft, "TimePicker");
    }
}

@Override
public void onStop() {
    super.onStop();
    if (tp.isAdded()) tp.dismiss();
}

public static class TimePick extends android.app.DialogFragment implements TimePickerDialog.OnTimeSetListener {

    private EditText editText;

    public TimePick(EditText editText) {
        this.editText = editText;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        return new TimePickerDialog(getActivity(), this, hour, minute, DateFormat.is24HourFormat(getActivity()));
    }

    @Override
    public void onTimeSet(TimePicker view, int hourofDay, int minute) {
        editText.setText(Integer.toString(hourofDay) + ":" + Integer.toString(minute));
    }
}

this code won't try to create new time picker if any is on screen. You could pass target edittext to timePicker fragment. When you need values from these edittexts(your a,b,c,d... variables) you could read it when needed, not in onTimeSetMethod.

onStop method was provided to handle activity recreation cases. Here i just hide active timepicker.

Upvotes: 2

Neil
Neil

Reputation: 664

You are adding the same DialogFragment instance twice, to fix this, check whether TimePicker is added with getFragmentManager.findFragmentByTag("TimePicker").

Upvotes: 1

Related Questions