Ollie C
Ollie C

Reputation: 28509

How to configure DatePicker for date of birth date selection

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.

Upvotes: 13

Views: 13894

Answers (3)

Andreo Romera
Andreo Romera

Reputation: 100

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);

Upvotes: 2

Paul Spiesberger
Paul Spiesberger

Reputation: 5770

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

Upvotes: 2

Ollie C
Ollie C

Reputation: 28509

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"
    >

Upvotes: 7

Related Questions