Android DatePicker 更改为仅月和年

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21321789/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:21:32  来源:igfitidea点击:

Android DatePicker change to only Month and Year

androiddatedialog

提问by user3160725

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

我有一个 DatePickerDialog,我只想查看月和年。如何更改此代码?

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

谢谢

采纳答案by mohammed momn

Try the following code. It will show a DatePickerwith only the year and month (without day)

试试下面的代码。它将显示DatePicker只有年和月(没有日)

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 onClickmethod add the following code to display your dialog.

此方法返回一个日期选择器对话框。因此,在您的按钮onClick方法中添加以下代码以显示您的对话框。

createDialogWithoutDateField().show();

回答by Stephan Klein

As i recently stumbled across this problem myself, i tested multiple solutions from this post and similar questions on Stackoverflow.

由于我最近自己偶然发现了这个问题,因此我测试了这篇文章中的多个解决方案以及 Stackoverflow 上的类似问题。

Unfortunately i found no working solution especially for Android 5+

不幸的是,我没有找到特别适用于 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.

我最终实现了我自己的简单 DialogFragment 嵌入两个 NumberPickers。这应该与 3.0 及更高版本的所有版本兼容。

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

回答by Everton Fernandes Rosario

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 DatePickerDialogworks on API LEVEL >= 11.

请注意,该.getDatePicker()方法DatePickerDialog适用于API LEVEL >= 11.

In addition it does not work on API LEVEL >= 21.

此外,它不适用于 API LEVEL >= 21。

回答by Jawad Zeb

More Advance form of Stephan KleinAnswer .

Stephan KleinAnswer 的更高级形式。

As I have a requirement to make Year optional. And I have also handled date like february 28and also handle leap year.

因为我需要将Year设为optional。而且我也处理过像2 月 28日这样的日期,也处理过闰年

MonthYearPickerDialog

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

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>

回答by SHS

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.

'Xar E Ahmer' 的回答很容易理解,而且符合要求。我根据我的要求使用了相同的内容并进行了以下修改。

  • 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 ).
  • 'Xar E Ahmer' 答案的 Kotlin 转换。
  • 添加了一些错误处理案例。
  • 按闰年更多处理 2 月 28 日/29 日。
  • 每年复选框以排除年份(为用户简化)。

MonthYearPickerDialog.kt

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

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

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

回答by Andreas Rudolph

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

这是一个老问题,但现在您可以使用“BetterPickers”:

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

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

And use ExpirationPicker.

并使用 ExpirationPicker。

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

希望这可以为其他一些在 Google 上广泛搜索的迷失的灵魂解决这个问题。

回答by Malik Abu Qaoud

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