Android DatePicker 更改为仅月和年
Posted
技术标签:
【中文标题】Android DatePicker 更改为仅月和年【英文标题】:Android DatePicker change to only Month and Year 【发布时间】:2014-01-23 23:53:43 【问题描述】:我有一个 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();
;
谢谢
【问题讨论】:
请看这个链接。这个问题以前有人问过。 ***.com/questions/10673842/… android - Hide date field in datepickerdialog的可能重复 【参考方案1】:由于我最近自己偶然发现了这个问题,因此我测试了这篇文章中的多个解决方案以及 *** 上的类似问题。
不幸的是,我没有找到特别适用于 Android 5+ 的有效解决方案
我最终实现了我自己的嵌入两个 NumberPicker 的简单 DialogFragment。这应该与 3.0 及更高版本的所有版本兼容。
代码如下:
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();
还有布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<LinearLayout
android:layout_
android:layout_
android:layout_gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/picker_month"
android:layout_
android:layout_
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp">
</NumberPicker>
<NumberPicker
android:id="@+id/picker_year"
android:layout_
android:layout_>
</NumberPicker>
</LinearLayout>
</LinearLayout>
要显示布局,请使用:
MonthYearPickerDialog pd = new MonthYearPickerDialog();
pd.setListener(this);
pd.show(getFragmentManager(), "MonthYearPickerDialog");
【讨论】:
非常适合我。唯一的问题是默认的 onDateSet 是这种格式: onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) |但在您的自定义对话框中,它是 listener.onDateSet(null, 0, monthPicker.getValue(), yearPicker.getValue()); |因此,您将年份设置为“dayOfMonth” 谢谢!在 Android 6.0 上运行良好。 对于 API 28,您应该使用getSupportFragmentManager()
而不是 getFragmentManager()
。
不知道为什么,但我无法设置listener.onDateSet(null, yearPicker.getValue(), monthPicker.getValue(), 0);
我不得不将第一个参数更改为DatePicker(context)
。它一直向我显示 non-null value set to null 错误。希望对你有帮助
为我工作。谢谢【参考方案2】:
我不推荐使用反射来做这种事情。
有一种更简单、更漂亮的方法:
((ViewGroup) datePickerDialog.getDatePicker()).findViewById(Resources.getSystem().getIdentifier("day", "id", "android")).setVisibility(View.GONE);
请注意,DatePickerDialog
中的 .getDatePicker()
方法适用于 API LEVEL >= 11
。
此外,它不适用于 API LEVEL >= 21。
【讨论】:
对于我们这些不熟悉DatePicker
s 的人,您必须在使用此之前申请android:calendarViewShown="false"
。
它在 Android Studio 中不工作,但在 Eclipse 上工作正常,有什么原因吗??
@EvertonFernandesRosario API LEVEL >= 21 的任何解决方法.??
@EvertonFernandesRosario 这不适用于 nought(7.0)【参考方案3】:
试试下面的代码。它将显示一个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;
此方法返回一个日期选择器对话框。因此,在您的按钮的onClick
方法中添加以下代码以显示您的对话框。
createDialogWithoutDateField().show();
【讨论】:
看我的编辑答案,我测试代码并对其进行一些更改,它与我合作得很好,尝试并反馈给我 非常感谢。请看我的其他问题?[***.com/questions/21343408/… 让我们continue this discussion in chat 反射调用类中可用的方法。这种方法可能会在下一个版本的 Android 中消失得无影无踪。反射不是好的选择。 反射,或修改布局以隐藏列始终是一个 hacky 解决方案,并且从长远来看很容易崩溃。相反,应该真正制作自己的组件。请参阅 Stephan 对此问题的回答:***.com/a/31653048/1026805【参考方案4】:Stephan Klein 答案的更多高级形式。
因为我要求将 年份设为可选。我还处理了 2 月 28 日 之类的日期,还处理了 闰年。
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;
我这样称呼它
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_
android:layout_
android:orientation="vertical">
<LinearLayout
android:layout_
android:layout_
android:layout_gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/picker_month"
android:layout_
android:layout_
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp" />
<NumberPicker
android:id="@+id/picker_day"
android:layout_
android:layout_
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp" />
<NumberPicker
android:id="@+id/picker_year"
android:layout_
android:layout_ />
</LinearLayout>
</LinearLayout>
【讨论】:
也请分享month_year_picker
布局。
@ShajeelAfzal 我已经添加了它
@Nepster 是否适用于 android lollipop 及以上版本?
@Nepster 可以分享DateTimeOp
类的代码吗?【参考方案5】:
聚会迟到了。但是如果有人在寻找 Kotlin 版本,我会重写 @Stephan Klein 的 anwser,将其更改为 Kotlin,具有数据绑定样式、月份显示和日期输入。
所以,如果您正在寻找月份-年份选择器,您可以创建 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()
使用它的 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_
android:layout_
android:gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/pickerYear"
android:layout_
android:layout_
android:layout_marginEnd="20dp" />
<NumberPicker
android:id="@+id/pickerMonth"
android:layout_
android:layout_ />
</LinearLayout>
</layout>
要使用它,请调用:
MonthYearPickerDialog(date).apply
setListener view, year, month, dayOfMonth ->
Toast.makeText(requireContext(), "Set date: $year/$month/$dayOfMonth", Toast.LENGTH_LONG).show()
show(supportFragmentManager, "MonthYearPickerDialog")
看起来像这样:
在 Fragment 中使用时的注意事项
由于 Kotlin apply
将隐藏关键字 this
,并且 MonthYearPickerDialog
也是 Fragment
,因此您必须确保在 show()
方法中调用正确的 FragmentManager
。否则 FATAL IllegalStateException: not associated with a fragment manager.
可能会引发。
例如,如果你想在MyFragment
中调用这个,使用@来指定哪个“this”是:
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")
如果答案有帮助,请点赞:)
【讨论】:
带有android:descendantFocusability="blocksDescendants"
@FaizanHaidarKhan 根和<layout>
是视图绑定结构的一部分。您可以将其与Binding
类一起删除,并用老式的findViewById
方法替换它们,就可以了;)【参考方案6】:
“Xar E Ahmer”的答案很容易理解,而且符合要求。根据我的要求,我使用了相同的内容并进行了以下修改。
“Xar E Ahmer”答案的 Kotlin 转换。 添加了一些错误处理案例。 闰年 2 月 28 日/29 日的更多交割。 每年复选框以排除年份(为用户简化)。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 -> this@MonthYearPickerDialog.dialog.cancel()
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_
android:layout_
android:orientation="vertical">
<CheckBox
android:id="@+id/datepicker_isyearcheckBox"
android:layout_
android:layout_
android:checked="false"
android:layout_gravity="center"
android:paddingTop="20dp"
android:paddingBottom="20dp"
android:text="Every year" />
<LinearLayout
android:layout_
android:layout_
android:layout_gravity="center"
android:orientation="horizontal">
<NumberPicker
android:id="@+id/datepicker_month"
android:layout_
android:layout_
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp" />
<NumberPicker
android:id="@+id/datepicker_day"
android:layout_
android:layout_
android:layout_marginEnd="20dp"
android:layout_marginRight="20dp" />
<NumberPicker
android:id="@+id/datepicker_year"
android:layout_
android:layout_ />
</LinearLayout>
</LinearLayout>
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);
对于想要“日期”对象作为返回值的用户:-
我们可以根据以下返回的日、月和年值创建日期对象(请更正任何语法错误)
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);
【讨论】:
【参考方案7】:它对我有用...试试这个
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();
);
【讨论】:
【参考方案8】:这是一个老问题,但现在你可以使用“BetterPickers”:
https://github.com/code-troopers/android-betterpickers
并使用 ExpirationPicker。
希望这能为那些在谷歌上广泛搜索的其他一些迷失的灵魂解决这个问题。
【讨论】:
我检查了ExpirationPicker
,问题是它只能选择即将到来的年份和月份。我的意思是,我们不能选择“1970 年 4 月”。只是未来的日期。所以,这个答案没有回答问题......【参考方案9】:
只需在代码中添加这一行即可。
一天
datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("day","id","android")).visibility = View.GONE
月份
datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("month","id","android")).visibility = View.GONE
一年
datePickerDialog.datePicker.findViewById<View (resources.getIdentifier("year","id","android")).visibility = View.GONE
【讨论】:
【参考方案10】:有一个定制的喷气背包组合解决方案。您可以仅选择月份、仅年份或同时选择两者。 https://github.com/DogusTeknoloji/compose-date-picker
【讨论】:
【参考方案11】:这对我来说很好:
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();
【讨论】:
这个在 Oxygen OS,一加 X 上提供 NPE,因为它找不到具有该 ID 的视图。以上是关于Android DatePicker 更改为仅月和年的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Bootstrap Datepicker Anchor Position 更改为居中?
在 Datepicker 中将日期格式更改为 yyyy-mm-dd
typescript 将datepicker KendoUI更改为希伯来语
如何将datepicker日期格式更改为DD / MM / YYYY [复制]