How to configure DatePicker for date of birth date selection

10,562

Solution 1

The last three attributes on the DatePicker below do the trick, as it switches the DatePicker from the "Calendar" view to use the three spinners for year, month and day:

<DatePicker
    android:id="@+id/datePicker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:calendarViewShown="false"
    android:datePickerMode="spinner"
    android:spinnersShown="true"
    >

Solution 2

I could only find this library as a proper solution, it's really a pity that Google messed this up:

https://github.com/drawers/SpinnerDatePicker

Solution 3

This is what you can do:

Styles.xml

<style name="CustomDatePickerDialog" parent="Theme.AppCompat.Light.Dialog.Alert">
    <item name="android:dialogTheme">@style/MyDialogTheme</item>
    <item name="android:datePickerStyle">@style/MyDatePicker</item>
</style>

<style name="MyDialogTheme" parent="Theme.AppCompat.Light.Dialog">
    <item name="android:datePickerStyle">@style/MyDatePicker</item>
</style>

<style name="MyDatePicker" parent="@android:style/Widget.Material.DatePicker">
    <item name="android:datePickerMode">spinner</item>
</style>

Define a new class, which represents a DialogFragment where your DatePicker will be presented:

public class DatePickerFragment extends DialogFragment implements DatePickerDialog.OnDateSetListener {
private final Calendar c = Calendar.getInstance();
private DatePickerListener listener;

public DatePickerFragment() {
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    int customStyle = -1;

    Bundle arguments = getArguments();
    if (arguments != null)
        customStyle = arguments.getInt("customStyle", -1);

    int year = c.get(Calendar.YEAR);
    int month = c.get(Calendar.MONTH);
    int day = c.get(Calendar.DAY_OF_MONTH);

    if (customStyle != -1)
        return new DatePickerDialog(getActivity(), customStyle, this, year, month, day);
    else
        return new DatePickerDialog(getActivity(), this, year, month, day);
}

@Override
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
    if (listener != null) {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy", Locale.US);

        c.set(Calendar.YEAR, year);
        c.set(Calendar.MONTH, month);
        c.set(Calendar.DAY_OF_MONTH, dayOfMonth);

        String data = sdf.format(c.getTime());

        listener.onDatePicked(data);
    }
}

public void setDatePickerListener(DatePickerListener listener) {
    this.listener = listener;
}

public interface DatePickerListener {
    void onDatePicked(String date);
}
}

In your activity or fragment, add a new method to bind the click event to your TextView:

private void setDatePicker(final TextView textView) {
    textView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            DatePickerFragment newFragment = new DatePickerFragment();

            Bundle b = new Bundle();
            b.putInt("customStyle", R.style.CustomDatePickerDialog);
            newFragment.setArguments(b);

            newFragment.setDatePickerListener(new DatePickerFragment.DatePickerListener() {
                @Override
                public void onDatePicked(String date) {
                    textView.setText(date);
                }
            });

            newFragment.show(getFragmentManager(), "datePicker");
        }
    });
}

and finally, in the onCreate() method, configure the TextView which should receive the selected date:

    dataNascText = v.findViewById(R.id.dataNascText);
    setDatePicker(dataNascText);
Share:
10,562
Ollie C
Author by

Ollie C

Freelance Android Developer in London SE1, UK. Contact me about your project [email protected] Please note that I ONLY work remotely from my home office. Most projects I take on are shorter, typically one to three months in duration.

Updated on June 17, 2022

Comments

  • Ollie C
    Ollie C about 2 years

    With the default display the DatePicker shows the current month, but the user may wish to select a date which is hundreds of months previous. It is of course possible to tap the year and select the birth year that way, but many users are not aware of this and most are clicking through the months to go back years to select the date of birth. It is causing a great deal of frustration.

    Is there a way to configure the Android DatePicker so that when it opens it asks the user to select the year first? Or is there a way of displaying the months so the user can slide through them more quickly rather than click? Or is it really necessary to create a UI in advance of the date picker to require them to select the year before the DatePicker opens? I find the DatePicker, for selecting dates some time ago, is very poor as its ease of use requires use of a feature that many users are just not aware of.

  • andrew
    andrew almost 6 years
    Don't know why this is downvoted. It worked fine for me. Tested on an emulator, a Pixel and an S6