Skip to content

Picker Dialogs

TR4Android edited this page Mar 3, 2016 · 2 revisions

This wiki hightlights the setup needed for using the AppCompatDatePickerDialog and AppCompatTimePickerDialog and the customization options available for each component. Here are a few of the advantages of using those dialogs:

  • Uses the design presented in the Pickers section of the Material Design guidelines for a fully Material Design compliant user experience!
  • Works all the way back to API level 7 while maintaining important features (such as accessibility and right-to-left support) on API levels that support those.

1. Setup your theme

In order for your picker dialogs to be correctly styled on all Android versions you'll need to setup you application theme first. As indicated in the following snippet, you'll have to add new styles for your AppCompatDatePickerDialog and your AppCompatTimePickerDialog (both styles need AppCompat themes as their parent):

<!-- style used for the AppCompatDatePickerDialog -->
<style name="DatePickerDialog" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">#009688</item>
</style>

<!-- style used for the AppCompatTimePickerDialog -->
<style name="TimePickerDialog" parent="Theme.AppCompat.Light.Dialog">
    <item name="colorAccent">#009688</item>
    <item name="numbersBackgroundColor">#ffeeeeee</item>
</style>

This is also the place where you apply all the custom style attributes available. Both the AppCompatDatePickerDialog and the AppCompatTimePickerDialog can be styled using the following attributes:

  • colorAccent: The overall accent color applied to the dialog (used e.g. for header, activated states and buttons).
  • headerBackground: The background color of the dialog header. Defaults to ?attr/colorAccent.
  • headerTextColor: The text color of the dialog header. Defaults to ?android:attr/textColorSecondary when not selected, and ?android:attr/textColorPrimary when selected.

In addition to those, the AppCompatDatePickerDialog can use the following attributes:

  • firstDayOfWeek: The weekday that represents the first day of a week. Default depends on locale.
  • minDate: The minimum date shown. Defaults to January 1st, 1900.
  • maxDate: The maximum date shown. Defaults to December 31st, 2100.
  • monthTextAppearance: The text appearance of the month title.
  • weekDayTextAppearance: The text appearance of the week days.
  • dateTextAppearance: The text appearance of the days. Needs to contain a selected state!
  • daySelectorColor: The background circle color of a day when it is selected. Defaults to ?attr/colorAccent.
  • dayHighlightColor: The background circle color of a day when it is pressed. Defaults to ?attr/colorControlHighlight.

And the AppCompatTimePickerDialog has the following additional attributes:

  • numbersTextColor: The text color of the outer numbers. Needs to contain a selected state!
  • numbersInnerTextColor: The text color of the inner numbers (only used in 24-hour mode). Needs to contain a selected state!
  • numbersSelectorColor: The background circle color of a number when it is selected. Defaults to ?attr/colorAccent.
  • numbersBackgroundColor: The background color of the large clock circle.

Then reference those newly created styles in your application theme, so they get properly applied when you create a new picker dialog (don't use the android: prefix here, as those attributes are not available on all API levels):

<!-- Base application theme. -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- other attributes -->

    <item name="datePickerDialogTheme">@style/DatePickerDialog</item>
    <item name="timePickerDialogTheme">@style/TimePickerDialog</item>
</style>

2. Create a picker dialog

After your theme is setup you're good to go. Creating and showing the picker dialogs is done in much the same way as it is done with the stock picker dialogs. Most of you should only need to replace DatePickerDialog with AppCompatDatePickerDialog and TimePickerDialog with AppCompatTimePickerDialog, as well as replacing DatePicker with AppCompatDatePicker and TimePicker with AppCompatTimePicker in your listener callbacks.

For reference, here's how you would create a new DialogFragment with an AppCompatDatePickerDialog and display it to the user:

public static class DatePickerFragment extends DialogFragment implements AppCompatDatePickerDialog.OnDateSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current date as the default values for the picker
        final Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        int month = c.get(Calendar.MONTH);
        int day = c.get(Calendar.DAY_OF_MONTH);

        // Create a new instance of AppCompatDatePickerDialog and return it
        return new AppCompatDatePickerDialog(getActivity(), this, year, month, day);
    }

    public void onDateSet(AppCompatDatePicker view, int year, int month, int day) {
        // Do something with the date chosen by the user
    }
}

public void showDatePicker() {
    // Show new DatePickerDialog
    DialogFragment datePicker = new DatePickerFragment();
    datePicker.show(getSupportFragmentManager(), "datePicker");
}

And here's how you would create a new DialogFragment with an AppCompatTimePickerDialog and display it to the user:

public static class TimePickerFragment extends DialogFragment implements AppCompatTimePickerDialog.OnTimeSetListener {

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the current time as the default values for the picker
        final Calendar c = Calendar.getInstance();
        int hour = c.get(Calendar.HOUR_OF_DAY);
        int minute = c.get(Calendar.MINUTE);

        // Create a new instance of TimePickerDialog and return it
        return new AppCompatTimePickerDialog(getActivity(), this, hour, minute, false);
    }

    public void onTimeSet(AppCompatTimePicker view, int hourOfDay, int minute) {
        // Do something with the time chosen by the user
    }
}

public void showTimePicker() {
    // Show new TimePickerDialog
    DialogFragment timePicker = new TimePickerFragment();
    timePicker.show(getSupportFragmentManager(), "timePicker");
}

3. Enjoy

Congrats! Now you can enjoy the new Material Design picker dialogs in all their splendor! As always, if you have any issues, bugs or feature requests please open a new issue.

Clone this wiki locally