-
Notifications
You must be signed in to change notification settings - Fork 42
Picker Dialogs
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.
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 toJanuary 1st, 1900
. -
maxDate
: The maximum date shown. Defaults toDecember 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>
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");
}
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.