Android DatePicker change to only Month and Year

AndroidDateDialog

Android Problem Overview


I have a DatePickerDialog and I want view only Month and Year. How can I change this code?

public void chooseDate2(View v) {
	new DatePickerDialog(
		act.this,
		d1,
		dateAndTime1.get(Calendar.YEAR) + 2,
		dateAndTime1.get(Calendar.MONTH),
		dateAndTime1.get(Calendar.DAY_OF_MONTH)
	).show();
}
private void updateLabel2() {
	scadenza.setText(fmtDateAndTime.format(dateAndTime1.getTime()));           
}
DatePickerDialog.OnDateSetListener d1=new DatePickerDialog.OnDateSetListener() {
	public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
		dateAndTime1.set(Calendar.YEAR, year);
		dateAndTime1.set(Calendar.MONTH, monthOfYear);
		dateAndTime1.set(Calendar.DAY_OF_MONTH, dayOfMonth);
		updateLabel2();
	}
};

Thanks

Android Solutions


Solution 1 - Android

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

Solution 2 - Android

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.

Solution 3 - Android

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

Solution 4 - Android

More Advance form of Stephan Klein Answer . > As I have a requirement to make Year optional. And I have also handled date like february 28 and also handle leap year.

MonthYearPickerDialog

public class MonthYearPickerDialog extends DialogFragment {

    private DatePickerDialog.OnDateSetListener listener;
    private int daysOfMonth = 31;

    private NumberPicker monthPicker;
    private NumberPicker yearPicker;
    private NumberPicker dayPicker;

    private Calendar cal = Calendar.getInstance();

    public static final String MONTH_KEY = "monthValue";
    public static final String DAY_KEY = "dayValue";
    public static final String YEAR_KEY = "yearValue";

    int monthVal = -1 , dayVal = -1 , yearVal =-1 ;

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle extras = getArguments();
        if(extras != null){
            monthVal = extras.getInt(MONTH_KEY , -1);
            dayVal = extras.getInt(DAY_KEY , -1);
            yearVal = extras.getInt(YEAR_KEY , -1);
        }
    }

    public static MonthYearPickerDialog newInstance(int monthIndex , int daysIndex , int yearIndex) {
        MonthYearPickerDialog f = new MonthYearPickerDialog();

        // Supply num input as an argument.
        Bundle args = new Bundle();
        args.putInt(MONTH_KEY, monthIndex);
        args.putInt(DAY_KEY, daysIndex);
        args.putInt(YEAR_KEY, yearIndex);
        f.setArguments(args);

        return f;
    }

    public void setListener(DatePickerDialog.OnDateSetListener listener) {
        this.listener = listener;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        //getDialog().setTitle("Add Birthday");

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        View dialog = inflater.inflate(R.layout.month_year_picker, null);
        monthPicker = (NumberPicker) dialog.findViewById(R.id.picker_month);
        yearPicker = (NumberPicker) dialog.findViewById(R.id.picker_year);
        dayPicker = (NumberPicker) dialog.findViewById(R.id.picker_day);

        monthPicker.setMinValue(1);
        monthPicker.setMaxValue(12);


        if(monthVal != -1)// && (monthVal > 0 && monthVal < 13))
            monthPicker.setValue(monthVal);
        else
            monthPicker.setValue(cal.get(Calendar.MONTH) + 1);

        monthPicker.setDisplayedValues(new String[]{"Jan","Feb","Mar","Apr","May","June","July",
                "Aug","Sep","Oct","Nov","Dec"});


        dayPicker.setMinValue(1);
        dayPicker.setMaxValue(daysOfMonth);

        if(dayVal != -1)
            dayPicker.setValue(dayVal);
        else
            dayPicker.setValue(cal.get(Calendar.DAY_OF_MONTH));

        monthPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                switch (newVal){
                    case 1:case 3:case 5:
                    case 7:case 8:case 10:
                    case 12:
                        daysOfMonth = 31;
                        dayPicker.setMaxValue(daysOfMonth);
                        break;
                    case 2:
                        daysOfMonth = 28;
                        dayPicker.setMaxValue(daysOfMonth);
                        break;

                    case 4:case 6:
                    case 9:case 11:
                        daysOfMonth = 30;
                        dayPicker.setMaxValue(daysOfMonth);
                        break;
                }

            }
        });

        int maxYear = cal.get(Calendar.YEAR);//2016
        final int minYear = 1916;//1997;
        int arraySize = maxYear - minYear;

        String[] tempArray = new String[arraySize];
        tempArray[0] = "---";
        int tempYear = minYear+1;

        for(int i=0 ; i < arraySize; i++){
            if(i != 0){
                tempArray[i] = " " + tempYear + "";
            }
            tempYear++;
        }
        Log.i("", "onCreateDialog: " + tempArray.length);
        yearPicker.setMinValue(minYear+1);
        yearPicker.setMaxValue(maxYear);
        yearPicker.setDisplayedValues(tempArray);

        if(yearVal != -1)
            yearPicker.setValue(yearVal);
        else
            yearPicker.setValue(tempYear -1);

        yearPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
            @Override
            public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
                try {
                    if(isLeapYear(picker.getValue())){
                        daysOfMonth = 29;
                        dayPicker.setMaxValue(daysOfMonth);
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        });


        builder.setView(dialog)
                // Add action buttons
                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        int year = yearPicker.getValue();
                        if(year == (minYear+1)){
                            year = 1904;
                        }
                        listener.onDateSet(null, year, monthPicker.getValue(), dayPicker.getValue());
                    }
                })
                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        MonthYearPickerDialog.this.getDialog().cancel();
                    }
                });

        return builder.create();
    }

    public static boolean isLeapYear(int year) {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, year);
        return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365;
    }
}

And I call it like

Calendar calendar = Calendar.getInstance();

        if(etBirthday.getText().length()> 0  ){
            if(checkIsYearAvailable(etBirthday.getText().toString().trim()))
                calendar = DateTimeOp.getCalendarFromFormat(etBirthday.getText().toString().trim(), Constants.dateFormat21);
            else
                calendar = DateTimeOp.getCalendarFromFormat(etBirthday.getText().toString().trim() + ", 1917",Constants.dateFormat21);
        }

        MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH),calendar.get(Calendar.YEAR));

        pd.setListener(new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {

                String formatedDate = "";

                if(selectedYear == 1904)
                {
                    String currentDateFormat = selectedMonth + "/" + selectedDay;// + "/" + selectedYear;  //"MM/dd/yyyy"
                    formatedDate = DateTimeOp.oneFormatToAnother(currentDateFormat, Constants.dateFormat20, Constants.dateFormat24);
                }
                else{
                    String currentDateFormat = selectedMonth + "/" + selectedDay + "/" + selectedYear;  //"MM/dd/yyyy"
                    formatedDate = DateTimeOp.oneFormatToAnother(currentDateFormat, Constants.dateFormat0, Constants.dateFormat21);
                }

                etBirthday.setText(formatedDate);
            }
        });
        pd.show(getFragmentManager(), "MonthYearPickerDialog");

month_year_picker.xml

<?xml version="1.0" encoding="utf-8"?>
	<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_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
            android:id="@+id/picker_day"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp" />

        <NumberPicker
            android:id="@+id/picker_year"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</LinearLayout>

Solution 5 - Android

Late to party. But if someone looking for Kotlin version, I re-write @Stephan Klein 's anwser, change it to Kotlin, with Data-Binding style, month display, and a date input.

So, if you're looking for an Month-Year picker, you can create Class MonthYearPickerDialog:

class MonthYearPickerDialog(val date: Date = Date()) : DialogFragment() {

    companion object {
        private const val MAX_YEAR = 2099
    }

    private lateinit var binding: DialogMonthYearPickerBinding

    private var listener: OnDateSetListener? = null

    fun setListener(listener: OnDateSetListener?) {
        this.listener = listener
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        binding = DialogMonthYearPickerBinding.inflate(requireActivity().layoutInflater)
        val cal: Calendar = Calendar.getInstance().apply { time = date }

        binding.pickerMonth.run {
            minValue = 0
            maxValue = 11
            value = cal.get(Calendar.MONTH)
            displayedValues = arrayOf("Jan","Feb","Mar","Apr","May","June","July",
                "Aug","Sep","Oct","Nov","Dec")
        }

        binding.pickerYear.run {
            val year = cal.get(Calendar.YEAR)
            minValue = year
            maxValue = MAX_YEAR
            value = year
        }

        return AlertDialog.Builder(requireContext())
            .setTitle("Please Select View Month")
            .setView(binding.root)
            .setPositiveButton("Ok") { _, _ -> listener?.onDateSet(null, binding.pickerYear.value, binding.pickerMonth.value, 1) }
            .setNegativeButton("Cancel") { _, _ -> dialog?.cancel() }
            .create()
    }
}

With its xml dialog_month_year_picker :

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="horizontal">

        <NumberPicker
            android:id="@+id/pickerYear"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp" />

        <NumberPicker
            android:id="@+id/pickerMonth"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</layout>

To use it, call:

MonthYearPickerDialog(date).apply {
    setListener { view, year, month, dayOfMonth ->
        Toast.makeText(requireContext(), "Set date: $year/$month/$dayOfMonth", Toast.LENGTH_LONG).show()
    }
    show(supportFragmentManager, "MonthYearPickerDialog")
}

It'll look like this:

Month-Year Picker Dialog

CAUTION When Used in Fragment

Since Kotlin apply will shadow keyword this, and MonthYearPickerDialog is also a Fragment, you must make sure you call the correct FragmentManager in show() method. Otherwise a FATAL IllegalStateException: not associated with a fragment manager. might raise.

For Example, if you want to call this in MyFragment, use @ to specify which "this" is:

MonthYearPickerDialog(date).apply {
    setListener { view, year, month, dayOfMonth ->
        Toast.makeText(requireContext(), "Set date: $year/$month/$dayOfMonth", Toast.LENGTH_LONG).show()
    }
    show(this@MyFragment.parentFragmentManager, "MonthYearPickerDialog")
}

Upvote if the answer helps :)

Solution 6 - Android

The answer by 'Xar E Ahmer' is very easy to follow and as per requirement. I have used the same with following modifications as per my requirement.

  • Kotlin conversion of 'Xar E Ahmer' Answer .
  • Few error handling case added.
  • More handing of February 28/29 as per leap year.
  • Every year checkbox to exclude year ( simplified for user ).

MonthYearPickerDialog.kt

package com.example.*******

import android.app.AlertDialog
import android.app.DatePickerDialog
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.CheckBox
import android.widget.CompoundButton
import android.widget.NumberPicker
import android.app.DialogFragment
import java.util.Calendar

class MonthYearPickerDialog : DialogFragment() {

    private var listener: DatePickerDialog.OnDateSetListener? = null
    private var daysOfMonth = 31

    private var monthPicker: NumberPicker? = null
    private var yearPicker: NumberPicker? = null
    private var dayPicker: NumberPicker? = null
    private var isEveryYearcheckBox: CheckBox? = null

    private val cal = Calendar.getInstance()

    internal var monthVal = -1
    internal var dayVal = -1
    internal var yearVal = -1
    internal var maxYearVal = -1
    internal var minYearVal = -1

    override fun onAttach(context: Context) {
        super.onAttach(context)
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val extras = arguments
        if (extras != null) {
            monthVal = extras.getInt(MONTH_KEY, -1)
            dayVal = extras.getInt(DAY_KEY, -1)
            yearVal = extras.getInt(YEAR_KEY, -1)
            maxYearVal = extras.getInt(MAX_YEAR_KEY, -1)
            minYearVal = extras.getInt(MIN_YEAR_KEY, -1)
        }
        maxYearVal = if (maxYearVal == -1) 2025 else maxYearVal
        minYearVal = if (minYearVal == -1) 1925 else minYearVal

        if (minYearVal > maxYearVal) {
            val tempVal = maxYearVal
            maxYearVal = minYearVal
            minYearVal = tempVal
        }
    }

    fun setListener(listener: DatePickerDialog.OnDateSetListener) {
        this.listener = listener
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {

        val builder = AlertDialog.Builder(activity)
        // Get the layout inflater
        val inflater = activity.layoutInflater

        val dialog = inflater.inflate(R.layout.month_year_picker, null)
        monthPicker = dialog.findViewById<View>(R.id.datepicker_month) as NumberPicker
        yearPicker = dialog.findViewById<View>(R.id.datepicker_year) as NumberPicker
        dayPicker = dialog.findViewById<View>(R.id.datepicker_day) as NumberPicker

        isEveryYearcheckBox = dialog.findViewById<View>(R.id.datepicker_isyearcheckBox) as CheckBox
        isEveryYearcheckBox!!.setOnCheckedChangeListener { compoundButton, b ->
            if (b) {
                yearPicker!!.isEnabled = false
                yearPicker!!.value = minYearVal - 1
            } else {
                yearPicker!!.isEnabled = true
                if (yearVal != -1 && yearVal != 1904)
                    yearPicker!!.value = yearVal
                else {
                    yearPicker!!.value = cal.get(Calendar.YEAR)
                }
            }
            if (monthPicker!!.value == 2) {
                daysOfMonth = 28
                if (isLeapYear(yearPicker!!.value)) {
                    daysOfMonth = 29
                }
                dayPicker!!.maxValue = daysOfMonth
            }
        }

        monthPicker!!.minValue = 1
        monthPicker!!.maxValue = 12

        if (monthVal != -1)
            monthPicker!!.value = monthVal
        else
            monthPicker!!.value = cal.get(Calendar.MONTH) + 1

        monthPicker!!.displayedValues = arrayOf("Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec")

        dayPicker!!.minValue = 1
        dayPicker!!.maxValue = daysOfMonth

        if (dayVal != -1)
            dayPicker!!.value = dayVal
        else
            dayPicker!!.value = cal.get(Calendar.DAY_OF_MONTH)

        monthPicker!!.setOnValueChangedListener { picker, oldVal, newVal ->
            when (newVal) {
                1, 3, 5, 7, 8, 10, 12 -> {
                    daysOfMonth = 31
                    dayPicker!!.maxValue = daysOfMonth
                }
                2 -> {
                    daysOfMonth = 28
                    if (isLeapYear(yearPicker!!.value)) {
                        daysOfMonth = 29
                    }
                    dayPicker!!.maxValue = daysOfMonth
                }

                4, 6, 9, 11 -> {
                    daysOfMonth = 30
                    dayPicker!!.maxValue = daysOfMonth
                }
            }
        }

        val maxYear = maxYearVal 
        val minYear = minYearVal 
        val arraySize = maxYear - minYear + 2

        val tempArray = arrayOfNulls<String>(arraySize)
        tempArray[0] = "---"
        var tempYear = minYear - 1

        for (i in 0 until arraySize) {
            if (i != 0) {
                tempArray[i] = " $tempYear"
            }
            tempYear++
        }
        Log.i("", "onCreateDialog: " + tempArray.size)
        yearPicker!!.minValue = minYear - 1
        yearPicker!!.maxValue = maxYear
        yearPicker!!.displayedValues = tempArray

        if (yearVal != -1 && yearVal != 1904) {
            yearPicker!!.value = yearVal
        } else {
            isEveryYearcheckBox!!.isChecked = false
            yearPicker!!.isEnabled = false
            yearPicker!!.value = minYear - 1
        }
        if (monthPicker!!.value == 2) {
            daysOfMonth = 28
            if (isLeapYear(yearPicker!!.value)) {
                daysOfMonth = 29
            }
            dayPicker!!.maxValue = daysOfMonth
        }

        yearPicker!!.setOnValueChangedListener { picker, oldVal, newVal ->
            try {
                daysOfMonth = 28
                if (isLeapYear(picker.value)) {
                    daysOfMonth = 29
                }
                dayPicker!!.maxValue = daysOfMonth
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }

        builder.setView(dialog)
                // Add action buttons
                .setPositiveButton(R.string.ok) { dialog, id ->
                    var year = yearPicker!!.value
                    if (year == minYear - 1) {
                        year = 1904
                    }
                    listener!!.onDateSet(null, year, monthPicker!!.value, dayPicker!!.value)
                }
                .setNegativeButton(R.string.cancel) { dialog, id -> [email protected]() }

        return builder.create()
    }

    companion object {

        val MONTH_KEY = "monthValue"
        val DAY_KEY = "dayValue"
        val YEAR_KEY = "yearValue"
        val MAX_YEAR_KEY = "maxyearValue"
        val MIN_YEAR_KEY = "minyearValue"

        fun newInstance(monthIndex: Int, daysIndex: Int, yearIndex: Int, maxYearIndex: Int, minYearIndex: Int): MonthYearPickerDialog {
        	
            val f = MonthYearPickerDialog()

            // Supply num input as an argument.
            val args = Bundle()
            args.putInt(MONTH_KEY, monthIndex)
            args.putInt(DAY_KEY, daysIndex)
            args.putInt(YEAR_KEY, yearIndex)
            args.putInt(MAX_YEAR_KEY, maxYearIndex)
            args.putInt(MIN_YEAR_KEY, minYearIndex)
            f.arguments = args

            return f
        }

        fun isLeapYear(year: Int): Boolean {
            val cal = Calendar.getInstance()
            cal.set(Calendar.YEAR, year)
            return cal.getActualMaximum(Calendar.DAY_OF_YEAR) > 365
        }
    }
}

month_year_picker.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <CheckBox
        android:id="@+id/datepicker_isyearcheckBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="false"
        android:layout_gravity="center"
        android:paddingTop="20dp"
        android:paddingBottom="20dp"
        android:text="Every year" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:orientation="horizontal">

        <NumberPicker
            android:id="@+id/datepicker_month"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp" />

        <NumberPicker
            android:id="@+id/datepicker_day"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:layout_marginRight="20dp" />

        <NumberPicker
            android:id="@+id/datepicker_year"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>
</LinearLayout>

Usage example with different test cases in JAVA

Calendar calendar = Calendar.getInstance();
// current date 
MonthYearPickerDialog pd = MonthYearPickerDialog.Companion.newInstance(calendar.get(Calendar.MONTH) + 1,
        calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.YEAR), -1, -1);
        
// SSTODO for testing
// no year
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), -1, -1, -1);
        
// minimum year 2020
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.YEAR), -1, 2020);

// maximum year 2018
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.YEAR), 2018, -1);

// maximum year 2019, minimum year 2019
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.YEAR), 2019, 2019);

// maximum year 100, minimum year 5000
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), calendar.get(Calendar.YEAR), 100, 5000);

// maximum year 100, minimum year 5000, year 99
//MonthYearPickerDialog pd = MonthYearPickerDialog.newInstance(calendar.get(Calendar.MONTH) + 1,
//        calendar.get(Calendar.DAY_OF_MONTH), 99, 100, 5000);

pd.setListener(new DatePickerDialog.OnDateSetListener() {
          @Override
          public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDay) {

              String formatedDate = "";
              String currentDateFormat = "";
              if(selectedYear == 1904)	// no year
              {
                  currentDateFormat = selectedMonth + "/" + selectedDay; //"MM/dd"
              }
              else {
                  currentDateFormat = selectedMonth + "/" + selectedDay + "/" + selectedYear;  //"MM/dd/yyyy"
              }
              Toast.makeText(MainActivityTestOne.this, "Selected Date ( MM/dd  or. MM/dd/yyyy ) : " + currentDateFormat, Toast.LENGTH_LONG).show();
          }
});
pd.show(getFragmentManager(), STRING_DATE_PICKER);

For the users, who wanted 'date' object as returned value:-

we can create date object from the returned day, Month and Year values as per following ( please correct any syntax error )

SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy");
String currentDateString = selectedDay + "-" selectedMonth + "-" + selectedYear; 
long millis = format.parse(currentDateString).getTime();

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis( millis );
int date = calendar.get(CALENDAR.DATE);

Solution 7 - Android

It Works For me... Try This

    monthPicker.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Calendar mcurrentDate = Calendar.getInstance();
              String myFormat = "MMMM yyyy";
              SimpleDateFormat sdf = new SimpleDateFormat(myFormat);
                DatePickerDialog monthDatePickerDialog = new DatePickerDialog(getActivity(),
                        AlertDialog.THEME_HOLO_LIGHT, new DatePickerDialog.OnDateSetListener() {
                    @Override
                    public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                        mcurrentDate.set(Calendar.YEAR, year);
                        mcurrentDate.set(Calendar.MONTH, month);
                        monthPicker.setText(sdf.format(mcurrentDate.getTime()));
                        mDay = dayOfMonth;
                        mMonth = month;
                        mYear = year;
                    }
                }, mYear, mMonth, mDay){
                    @Override
                    protected void onCreate(Bundle savedInstanceState) {
                        super.onCreate(savedInstanceState);
                        getDatePicker().findViewById(getResources().getIdentifier("day","id","android")).setVisibility(View.GONE);
                    }
                };
                monthDatePickerDialog.setTitle("Select month And Year");
                monthDatePickerDialog.show();
            }
        });

Solution 8 - Android

This is an old question, but now you can just use "BetterPickers":

https://github.com/code-troopers/android-betterpickers

And use ExpirationPicker.

Hope this solves it for some other lost souls who searched Google far and wide.

Solution 9 - Android

It's very simple and easy just add this line in your code.

For Day

datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("day","id","android")).visibility = View.GONE

For Month

datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("month","id","android")).visibility = View.GONE

For Year

datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("year","id","android")).visibility = View.GONE

Solution 10 - Android

There is a custom jetpack compose solution. You can select only month, only year or both. https://github.com/DogusTeknoloji/compose-date-picker

Solution 11 - Android

This Works for me fine :

DatePickerDialog monthDatePickerDialog = new DatePickerDialog(activity, 
AlertDialog.THEME_HOLO_LIGHT, new DatePickerDialog.OnDateSetListener() {
        @Override
        public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
            monthTextView.setText(year + "/" + (month + 1));
        }
    }, yearNow, monthNow, dayNow){
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getDatePicker().findViewById(getResources().getIdentifier("day","id","android")).setVisibility(View.GONE);
        }
    };
    monthDatePickerDialog.setTitle("select_month");
    monthDatePickerDialog.show();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser3160725View Question on Stackoverflow
Solution 1 - AndroidStephan KleinView Answer on Stackoverflow
Solution 2 - AndroidEverton Fernandes RosarioView Answer on Stackoverflow
Solution 3 - Androidmohammed momnView Answer on Stackoverflow
Solution 4 - AndroidZar E AhmerView Answer on Stackoverflow
Solution 5 - AndroidSamuel T. ChouView Answer on Stackoverflow
Solution 6 - AndroidSHSView Answer on Stackoverflow
Solution 7 - AndroidToufiqul Haque MamunView Answer on Stackoverflow
Solution 8 - AndroidAndreas RudolphView Answer on Stackoverflow
Solution 9 - AndroidAdam NoorView Answer on Stackoverflow
Solution 10 - Androidonur taskinView Answer on Stackoverflow
Solution 11 - AndroidMalik Abu QaoudView Answer on Stackoverflow