Combining date and time picker in one AlertDialog


#1

I know the actual question in the book is different, which explicitly states that the user shall be presented with a choice of editing either date or time. But they both can be modified in the same AlertDialog, at least on tablet screens it might be handy, which is what I present here. It kinda breaks down the learning spirit of the exercise which in my opinion is to understand how fragments communicate, but anyway here it goes…

public class DatePickerFragment extends DialogFragment {
    private Date mDate;
    private int year, month, day, hour, min;
    ....

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
    	mDate = (Date)getArguments().getSerializable(EXTRA_DATE);
    	
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(mDate);
        year = calendar.get(Calendar.YEAR);
        month = calendar.get(Calendar.MONTH);
        day = calendar.get(Calendar.DAY_OF_MONTH);
        hour = calendar.get(Calendar.HOUR_OF_DAY);
        min = calendar.get(Calendar.MINUTE);
        
        View v = getActivity().getLayoutInflater().inflate(R.layout.dialog_datetime, null);
        
        DatePicker datePicker = (DatePicker)v.findViewById(R.id.datePicker);
        TimePicker timePicker = (TimePicker)v.findViewById(R.id.timePicker);
        
        datePicker.init(year, month, day, new OnDateChangedListener() {
            public void onDateChanged(DatePicker view, int year, int month, int day) {
            	DatePickerFragment.this.year = year;
            	DatePickerFragment.this.month = month;
            	DatePickerFragment.this.day = day;
            	updateDateTime();
            }
        });
        
        timePicker.setCurrentHour(hour);
        timePicker.setCurrentMinute(min);
        timePicker.setOnTimeChangedListener(new TimePicker.OnTimeChangedListener() {
            public void onTimeChanged(TimePicker view, int hour, int min) {
            	DatePickerFragment.this.hour = hour;
            	DatePickerFragment.this.min = min;
            	updateDateTime();
            }
        });
        
        return new AlertDialog.Builder(getActivity())
            .setView(v)
            .setTitle(R.string.date_picker_title)
            .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    sendResult(Activity.RESULT_OK);
                }
             })
            .create();
    }
    
    public void updateDateTime() {
        mDate = new GregorianCalendar(year, month, day, hour, min).getTime();
        getArguments().putSerializable(EXTRA_DATE, mDate);
    }
}

Layout XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/datetimeHost" 
    android:orientation="vertical" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" >
    
    <DatePicker 
        android:id="@+id/datePicker" 
        android:calendarViewShown="false" 
       	android:layout_width="fill_parent" 
        android:layout_height="wrap_content" >
    </DatePicker>
    
    <TimePicker 
        android:id="@+id/timePicker" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" >
    </TimePicker>
</LinearLayout>

Result: