Android DatePicker change to only Month and Year
As i recently stumbled across this problem myself, i tested multiple solutions from this post and similar questions on Stackoverflow.
Unfortunately i found no working solution especially for Android 5+
I ended up with implementing my own simple DialogFragment embedding two NumberPickers. This should be compatible with all versions from 3.0 and upwards.
Here is the code:
public class MonthYearPickerDialog extends DialogFragment { private static final int MAX_YEAR = 2099; private DatePickerDialog.OnDateSetListener listener; public void setListener(DatePickerDialog.OnDateSetListener listener) { this.listener = listener; } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater LayoutInflater inflater = getActivity().getLayoutInflater(); Calendar cal = Calendar.getInstance(); View dialog = inflater.inflate(R.layout.date_picker_dialog, null); final NumberPicker monthPicker = (NumberPicker) dialog.findViewById(R.id.picker_month); final NumberPicker yearPicker = (NumberPicker) dialog.findViewById(R.id.picker_year); monthPicker.setMinValue(0); monthPicker.setMaxValue(11); monthPicker.setValue(cal.get(Calendar.MONTH)); int year = cal.get(Calendar.YEAR); yearPicker.setMinValue(year); yearPicker.setMaxValue(MAX_YEAR); yearPicker.setValue(year); builder.setView(dialog) // Add action buttons .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { MonthYearPickerDialog.this.getDialog().cancel(); } }); return builder.create(); }}
And the layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:orientation="horizontal"> <NumberPicker android:id="@+id/picker_month" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="20dp" android:layout_marginRight="20dp"> </NumberPicker> <NumberPicker android:id="@+id/picker_year" android:layout_width="wrap_content" android:layout_height="wrap_content"> </NumberPicker> </LinearLayout></LinearLayout>
To show the layout use:
MonthYearPickerDialog pd = new MonthYearPickerDialog();pd.setListener(this);pd.show(getFragmentManager(), "MonthYearPickerDialog");
I don't recommend using Reflection to do this kind of thing.
There is a simpler and more pretty way to do so:
((ViewGroup) datePickerDialog.getDatePicker()).findViewById(Resources.getSystem().getIdentifier("day", "id", "android")).setVisibility(View.GONE);
Be aware that .getDatePicker()
method from DatePickerDialog
works on API LEVEL >= 11
.
In addition it does not work on API LEVEL >= 21.
Try the following code. It will show a DatePicker
with only the year and month (without day)
private DatePickerDialog createDialogWithoutDateField() { DatePickerDialog dpd = new DatePickerDialog(this, null, 2014, 1, 24); try { java.lang.reflect.Field[] datePickerDialogFields = dpd.getClass().getDeclaredFields(); for (java.lang.reflect.Field datePickerDialogField : datePickerDialogFields) { if (datePickerDialogField.getName().equals("mDatePicker")) { datePickerDialogField.setAccessible(true); DatePicker datePicker = (DatePicker) datePickerDialogField.get(dpd); java.lang.reflect.Field[] datePickerFields = datePickerDialogField.getType().getDeclaredFields(); for (java.lang.reflect.Field datePickerField : datePickerFields) { Log.i("test", datePickerField.getName()); if ("mDaySpinner".equals(datePickerField.getName())) { datePickerField.setAccessible(true); Object dayPicker = datePickerField.get(datePicker); ((View) dayPicker).setVisibility(View.GONE); } } } } } catch (Exception ex) { } return dpd; }
This method returns a date picker dialog. So , in your button's onClick
method add the following code to display your dialog.
createDialogWithoutDateField().show();