Search code examples
javaandroidandroid-fragmentstimepicker

How do I extract the hours and minutes of two time picker dialogs in the same onTimeSet()?


I have already implemented time pickers on button press which are in a fragment (Work) but how can i extract the the hour and the minutes of both dialogs to separate variables using only one onTimeSet(), which is located in the MainActivity?

This is my onTimeSet() in my MainActivity:

    public void onTimeSet(TimePicker timePicker, int i, int i1) {
        TextView textView = (TextView)findViewById(R.id.textstart);
        textView.setText("Hour: "+ i + " Minutes: "+ i1);

        getSupportFragmentManager().getFragments();

    }

And this is my Work fragment:

Button timeButton = (Button) view.findViewById(R.id.timeButton);
        timeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment timePicker = new TimePicker_Fragment();
                timePicker.show(getFragmentManager(), "Time Picker");
            }
        });

        Button timeButton2 = (Button) view.findViewById(R.id.timeButton2);
        timeButton2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogFragment timePicker2 = new TimePicker_Fragment();
                timePicker2.show(getFragmentManager(), "Time Picker 2");
            }
        });

        return view;
    }

Solution

  • One option is to change the architecture of your application:

    Since the TimePickerFragment is the only one which can make sense of the TimePicker parameter in onTimeSet(), it is the logical choice for implementing the TimePickerDialog.OnTimeSetListener.

    The two instances of TimePicker_Fragment could report back to the hosting WorkFragment (and eventually the Activity) via some custom interface(s). Use some unique value (a String or an enum) to identify them in your custom version of onTimeSet().

    For example your Activity could implement a method as follows:

    @Override
    void onCustomTimeSet(String timePickerId, int hour, int minutes){
        switch(timePickerId){
            case "TIME_PICKER":
                // code for time  picker 1 here
                break;
            case "TIME_PICKER_2":
                // code for time  picker 1 here
                break;
        }
        // ...
    }
    

    ...which would be called by the implementation of the "normal" onTimeSet(TimePicker, int, int) in TimePicker_Fragment

    @Override
    void onTimeSet(TimePicker timePicker, int i, int i2){
        ((CustomTimePickerListener)getActivity()).onCustomTimeSet("TIME_PICKER_1", i, i2)
    }
    

    Another option is to take advantage of the fact that a TimePicker is a View, and Views can have a tag (which can be any type of Object, see View.setTag() ).

    So you can have TimePicker_Fragment set a tag to the TimePicker.

    Since the TimePicker is part of the TimePickerDialog, the easiest way to set the tag seems to be to have (again) TimePicker_Fragment implement TimePickerDialog.OnTimeSetListener. But this time, the Activity could implement the same interface:

    Code in TimePicker_Fragment

    void onTimeSet(TimePicker timePicker, int i, int i2){
        timePicker.setTag("TIME_PICKER");
        ((TimePickerDialog.OnTimeSetListener)getActivity()).onTimeSet(timePicker, i, i2);
    }
    

    Code in the Activity

    void onTimeSet(TimePicker timePicker, int i, int i2){
        String tag = (String)timePicker.getTag();
        switch(tag){
            case "TIME_PICKER":
                // code for time  picker 1 here
                break;
            case "TIME_PICKER_2":
                // code for time  picker 2 here
                break;
        }
        // ...
    }
    


    Code implementing the second solution for the three relevant components:

    MainActivity.java

    public class MainActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new Work()).commit();
        }
    
        public void onTimeSet(TimePicker timePicker, int i, int i1){
            String tag = (String)timePicker.getTag();
            switch(tag){
                case TIME_PICKER:
                    TextView textView = (TextView)findViewById(R.id.textstart);
                    textView.setText("Start Hour: "+ i + " Minutes: "+ i1);
                    break;
                case TIME_PICKER_2:
                    TextView textView2 = (TextView)findViewById(R.id.textend);
                    textView2.setText("Start Hour: "+ i + " Minutes: "+ i1);
                    break;
            }
        }
    }
    

    Work.java

    public class Work extends Fragment {
    
        public static final String TIME_PICKER = "TIME_PICKER";
        public static final String TIME_PICKER_2 = "TIME_PICKER_2";
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.frag_work, container, false);
            getActivity().setTitle("Work");
    
            Button timeButton = (Button) view.findViewById(R.id.btn1);
            timeButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    DialogFragment timePicker = TimePicker_Fragment.instance(TIME_PICKER);
                    timePicker.show(getFragmentManager(), "Time Picker");
                }
            });
    
            Button timeButton2 = (Button) view.findViewById(R.id.btn2);
            timeButton2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    DialogFragment timePicker2 =TimePicker_Fragment.instance(TIME_PICKER_2);
                    timePicker2.show(getFragmentManager(), "Time Picker 2");
                }
            });
    
            return view;
        }
    }
    

    TimePicker_Fragment.java

    public class TimePicker_Fragment extends DialogFragment implements TimePickerDialog.OnTimeSetListener {
    
        private static final String KEY_TIMEPICKER_TAG = "KEY_TIMEPICKER_TAG";
    
        /**
         *
         * @param timePickerTag the tag by which you can identify a TimePicker.  
         *             Will be set as tag to the TimePicker View in onTimeSet()
         * @return x
         */
        public static TimePicker_Fragment instance(String timePickerTag){
            TimePicker_Fragment fragment = new TimePicker_Fragment();
            Bundle b = new Bundle();
            b.putString(KEY_TIMEPICKER_TAG, timePickerTag);
            fragment.setArguments(b);
            return fragment;
        }
    
        @NonNull
        @Override
        public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
            Calendar c = Calendar.getInstance();
            int hour = c.get(Calendar.HOUR_OF_DAY);
            int minute = c.get(Calendar.MINUTE);
            Context ctx = getContext();
            return new TimePickerDialog(ctx, this, hour, minute, DateFormat.is24HourFormat(ctx));
        }
    
        public void onTimeSet(TimePicker timePicker, int i, int i2){
            Bundle b = getArguments();
            assert b != null;
            timePicker.setTag(b.getString(KEY_TIMEPICKER_TAG));
            ((TimePickerDialog.OnTimeSetListener)getActivity()).onTimeSet(timePicker, i, i2);
        }
    }