Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 975
John Avatar asked Oct 20 '22 00:10

John


1 Answers

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.

like image 127
Beloo Avatar answered Oct 21 '22 19:10

Beloo