api级别11之前的Android datepicker min max date
Posted
技术标签:
【中文标题】api级别11之前的Android datepicker min max date【英文标题】:Android datepicker min max date before api level 11 【发布时间】:2012-06-05 21:24:31 【问题描述】:我正在尝试将 android 中日期选择器的最小和最大日期设置为 API 级别 11 之前。我使用了以下代码:
mDatePickerField = startDatePickerDialog.getClass().getDeclaredField("mDatePicker");
mDatePickerField.setAccessible(true);
DatePicker startDatePickerInstance =(DatePicker)mDatePickerField.get(startDatePickerDialog);
startDatePickerInstance.init(mYearMin, mMonthMin, mDayMin, new DatePicker.OnDateChangedListener()
@Override
public void onDateChanged(DatePicker datePicker, int i, int i1, int i2)
Date maxDate = new Date(mYearMax, mMonthMax, mDayMax, 0, 0, 0);
Date selectedDate = new Date(i, i1, i2, 0, 0, 0);
if (selectedDate.after(maxDate))
datePicker.updateDate(mYearMax, mMonthMax, mDayMax);
但是,updateDate
方法会再次触发 onDateChanged
,并且日期选择器不会更新。
谁能帮忙解决这个问题?
【问题讨论】:
【参考方案1】:您可以使用 init datePicker 方法设置范围。 最小值示例:
// Calendar
this.calendar = new GregorianCalendar();
this.datePicker = (DatePicker) findViewById(R.id.xxxxx);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
// (picker is a DatePicker)
this.datePicker.setMinDate(this.calendar.getTimeInMillis());
else
final int minYear = this.calendar.get(Calendar.YEAR);
final int minMonth = this.calendar.get(Calendar.MONTH);
final int minDay = this.calendar.get(Calendar.DAY_OF_MONTH);
this.datePicker.init(minYear, minMonth, minDay,
new OnDateChangedListener()
public void onDateChanged(DatePicker view, int year,
int month, int day)
Calendar newDate = Calendar.getInstance();
newDate.set(year, month, day);
if (calendar.after(newDate))
view.init(minYear, minMonth, minDay, this);
);
Log.w(TAG, "API Level < 11 so not restricting date range...");
【讨论】:
newDate.after(calendar)
用于设置MAX Date
和calendar.after(newDate)
用于设置MIN Date
你知道如何同时使用 MIN 和 MAX,使用这种方法我似乎无法实现这一点
您也可以使用反射获取归档***.com/questions/10507607/…【参考方案2】:
这个 DatePicker 自定义类允许我们指定最大和最小日期
public class DatePickerDialogWithMaxMinRange extends DatePickerDialog
static int maxYear=2005;
static int maxMonth=11;
static int maxDay=31;
int minYear=1955;
int minMonth=0;
int minDay=1;
public DatePickerDialogWithMaxMinRange(Context context, OnDateSetListener callBack,int minYear,int minMonth,int minDay,int maxYear,int maxMonth,int maxDay)
super(context,callBack, maxYear, maxMonth, maxDay);
this.minDay = minDay;
this.minMonth = minMonth;
this.minYear = minYear;
DatePickerDialogWithMaxMinRange.maxDay = maxDay;
DatePickerDialogWithMaxMinRange.maxMonth = maxMonth;
DatePickerDialogWithMaxMinRange.maxYear = maxYear;
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
super.onDateChanged(view, year, monthOfYear, dayOfMonth);
if (year > maxYear ||monthOfYear > maxMonth && year == maxYear||
dayOfMonth > maxDay && year == maxYear && monthOfYear == maxMonth)
view.updateDate(maxYear, maxMonth, maxDay);
else if(year < minYear ||monthOfYear < minMonth && year == minYear||
dayOfMonth < minDay && year == minYear && monthOfYear == minMonth)
view.updateDate(minYear, minMonth, minDay );
// 在您的 Activity 类或 Fragment 中使用此代码 指定成员为
private int intCurrentYear;
private int intCurrentMonth;
private int intCurrentDay;
private int intMaxYear;
private int intMaxMonth;
private int intMaxDay;
private int intMinYear;
private int intMinDay;
private int intMinMonth;
DatePickerDialogWithMaxMinRange datePickerDialog= null;
DatePickerDialog.OnDateSetListener datePickerOnDateSetListener;
Calendar myCalendar;
// 在 onCreate 或任何你想调用的地方调用这个方法..
注意:在 datepicker 对话框中选择后,您需要通过监听器自定义 datepickerdialog 来更新日期
public void setDate()
/*
* Initialise Listener for date set
*/
datePickerOnDateSetListener = new DatePickerDialog.OnDateSetListener()
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth)
edtTxtPlayerBirthDay.setText(new StringBuilder().append(year)
.append("-").append(monthOfYear + 1).append("-")
.append(dayOfMonth));
;
// initialise DatePicker
myCalendar = Calendar.getInstance();
intCurrentYear = myCalendar.get(Calendar.YEAR);
intCurrentMonth = myCalendar.get(Calendar.MONTH);
intCurrentDay = myCalendar.get(Calendar.DAY_OF_MONTH);
intMaxYear = intCurrentYear - 2000;
intMaxMonth = intCurrentMonth;
intMaxDay = intCurrentDay;
intMinYear = intCurrentYear - 1950;
intMinMonth = intCurrentMonth;
intMinDay = intCurrentDay;
datePickerDialog = new DatePickerDialogWithMaxMinRange(
context, datePickerOnDateSetListener,intMinYear,intMinMonth,intMinDay,intMaxYear,intMaxMonth,intMaxDay);
在创建日期选择器时,根据您的要求传递 mindate 和 maxdate 用于在单击按钮时显示日期选择器或任何其他控件将此代码放入该 onclicklistener...
datePickerDialog.show();
【讨论】:
老兄,你知道当你写 "abc" + 1 + object 它实际上是 new StringBUilder()... blah blah blah ...?正确的?那你为什么要手动写呢 @Ramesh 在 Android 5.0.1 中失败了,所以请提供一些替代解决方案。【参考方案3】:找到了一种很酷的方法来为DatePickerDialog
设置min
和max
日期。适用于所有 Android 版本。只需根据Android版本返回DatePickerDialog
protected Dialog onCreateDialog(int id)
switch ( id )
case DATE_DIALOG_ID:
DatePickerDialog dialog = null;
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB )
dialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener()
@Override
public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDate)
mTextView.setText(selectedDate + "/" + selectedMonth + 1 + "/" + selectedYear);
, year, month - 1, date);
Calendar currentDate = Calendar.getInstance();
dialog.getDatePicker().setMaxDate(currentDate.getTimeInMillis());
//If you need you can set min date too
else
dialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener()
@Override
public void onDateSet(DatePicker view, int selectedYear, int selectedMonth, int selectedDate)
mTextView.setText(selectedDate + "/" + selectedMonth + 1 + "/" + selectedYear);
, year, month - 1, date)
@Override
public void onDateChanged(DatePicker view, int year, int month, int day)
if ( year <= maxYear && month + 1 <= maxMonth && date <= maxDate ) //meets your criteria
view.updateDate(year, month, date); //update the date picker to selected date
else
view.updateDate(maxYear, maxMonth - 1, maxDate); // or you update the date picker to previously selected date
;
return dialog;
return null;
【讨论】:
【参考方案4】:编辑您的 DatePicker.java,添加以下 3 个代码摘录。
声明用于限制最小和最大日期的变量。
// Variables for defining minimum date
private int minimumDay;
private int minimumMonth;
private int minimumYear;
// Variables for defining maximum date
private int maximumDay;
private int maximumMonth;
private int maximumYear;
在构造函数之后,你必须重写 onDateChanged 方法。
// Called every time the user changes DatePicker values
public void onDateChanged(DatePicker view, int year, int monthOfYear,
int dayOfMonth)
// Test if chosen date is before minimum date
boolean beforeMinDate = false;
boolean afterMaxDate = false;
if(year < minimumYear)
beforeMinDate = true;
else if(year == minimumYear)
if(monthOfYear < minimumMonth)
beforeMinDate = true;
else if(monthOfYear == minimumMonth)
if(dayOfMonth < minimumDay)
beforeMinDate = true;
// Test if chosen date is after maximum date
if(!beforeMinDate)
if(year > maxYear)
afterMaxDate = true;
else if(year == maxYear)
if(monthOfYear > maxMonth)
afterMaxDate = true;
else if(monthOfYear == maxMonth)
if(dayOfMonth > maxDay)
afterMaxDate = true;
// If chosen date is before minimum date, update the date and internal
// calendar to minimum date, else, check similarly fot the maximum
// date, else, use the valid chosen date.
if(beforeMinDate)
mCalendar.set(minimumYear, minimumMonth, minimumDay,
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE));
updateDate(minimumYear, minimumMonth, minimumDay);
else if (afterMaxDate)
mCalendar.set(maximumYear, maximumMonth, maximumDay,
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE));
updateDate(maximumYear, maximumMonth, maximumDay);
else
mCalendar.set(year, monthOfYear, dayOfMonth,
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE));
现在,为最小和最大日期创建 setter 方法。
// Method to define minimum permitted date for the picker.
public void setMinimumDate(int minimumDay, int minimumMonth,
int minimumYear)
this.minimumDay = minimumDay;
this.minimumMonth = minimumMonth;
this.minimumYear = minimumYear;
//Method to define maximum permitted date for the picker.
public void setMaximumDate(int maximumDay, int maximumMonth,
int maximumYear)
this.maximumDay = maximumDay;
this.maximumMonth = maximumMonth;
this.maximumYear = maximumYear;
第二部分,在您调用 DatePicker 对话框的活动中,您需要设置所需的最小和最大日期。下面的代码将当前日期设置为最小日期,将未来两年设置为最大日期。
// Define current date as the minimum desired date
Calendar c = Calendar.getInstance();
int currentDay = c.get(Calendar.DAY_OF_MONTH);
int currentMonth = c.get(Calendar.MONTH);
int currentYear = c.get(Calendar.YEAR);
inicioDateTimePicker.setMinimumDate(currentDay, currentMonth,
currentYear);
// Define two years in the future as the maximum desired date
Calendar c = Calendar.getInstance();
int currentDay = c.get(Calendar.DAY_OF_MONTH);
int currentMonth = c.get(Calendar.MONTH);
int currentYear = c.get(Calendar.YEAR);
inicioDateTimePicker.setMinimumDate(currentDay, currentMonth,
currentYear + 2);
【讨论】:
【参考方案5】:你不能。我处理这个问题的方法是对 DatePicker 使用 if 语句:
import android.os.Build.*;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
// (picker is a DatePicker)
picker.setMinDate(...);
else
Log.w(TAG, "API Level < 11 so not restricting date range...");
我最终没有为 TimePicker 做任何事情。
有什么好消息?
SimonVT 已向后移植 DatePicker 和 TimePicker,因此您可以在早期 API 级别享受最新功能:
https://github.com/SimonVT/android-datepicker https://github.com/SimonVT/android-timepicker【讨论】:
【参考方案6】:根据@yostyle 的回答,我制作了一种方法来设置DatePicker 的最小和最大日期。 我的 DatePicker 在 AlertDialog 中使用,因为我需要一些额外的自定义,但是此方法可以直接用于任何 DatePickerDialog 或任何自定义 DatePicker:
/**
* Compat utility method that will set the minimum date and the maximum date for the DatePicker view.
* <p/>
* If the current API is greater than 11, than the normal @link android.widget.DatePicker#setMinDate(long) and
* @link android.widget.DatePicker#setMaxDate(long) methods will be used.
* <p/>
*
* @param minCalendar
* The minimum date for the picker
* @param maxCalendar
* The maximum date for the picker
*/
private void initDatePickerCompat(final Calendar minCalendar, final Calendar maxCalendar)
if (null == mDatePicker)
// Exit early if DatePicker view was not initialized
return;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
// (mDatePicker is a DatePicker)
mDatePicker.setMinDate(minCalendar.getTimeInMillis());
mDatePicker.setMaxDate(maxCalendar.getTimeInMillis());
else
final int minYear = minCalendar.get(Calendar.YEAR);
final int minMonth = minCalendar.get(Calendar.MONTH);
final int minDay = minCalendar.get(Calendar.DAY_OF_MONTH);
final int maxYear = maxCalendar.get(Calendar.YEAR);
final int maxMonth = maxCalendar.get(Calendar.MONTH);
final int maxDay = maxCalendar.get(Calendar.DAY_OF_MONTH);
mDatePicker.init(minYear, minMonth, minDay, new DatePicker.OnDateChangedListener()
@Override
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth)
Calendar newCalendar = Calendar.getInstance();
newCalendar.set(year, monthOfYear, dayOfMonth);
if (newCalendar.after(maxCalendar))
// MAX
view.updateDate(maxYear, maxMonth, maxDay);
else if (newCalendar.before(minCalendar))
// MIN
view.updateDate(minYear, minMonth, minDay);
else
// BETWEEN
view.updateDate(year, monthOfYear, dayOfMonth);
);
请记住,这个方法应该在 DatePicker 初始化之后调用,如下所示:
mDatePicker = (DatePicker) view.findViewById(R.id.datePicker);
mDatePicker.init(year, monthOfYear, dayOfMonth, this);
DateTime minDate = new DateTime();
DateTime maxDate = minDate.plusYears(10);
// Set the minimum and the maximum date for the date picker
initDatePickerCompat(minDate.toCalendar(Locale.getDefault()), maxDate.toCalendar(Locale.getDefault()));
【讨论】:
【参考方案7】:只需使用来自日历的 Value(Min & Max) 来设置 DatePiker.MaxDate & DatePiker.MinDate 尝试一些类似的东西:
DatePickerDialog dialog = new DatePickerDialog();
Java.Util.TimeZone GMT = new SimpleTimeZone(TimeZoneInfo.Local.BaseUtcOffset.Hours, "GMT");
Calendar maxDate = Calendar.GetInstance(GMT);
maxDate.Set(DateTime.Now.Year, DateTime.Now.Month - 1, DateTime.Now.Day);
Calendar minDate = Calendar.GetInstance(GMT);
minDate.Set(DateTime.Now.Year - 2, DateTime.Now.Month - 1, DateTime.Now.Day);
dialog.DatePicker.MaxDate = maxDate.TimeInMillis;
dialog.DatePicker.MinDate = minDate.TimeInMillis;
【讨论】:
以上是关于api级别11之前的Android datepicker min max date的主要内容,如果未能解决你的问题,请参考以下文章
Android API 级别 30 setSystemBarsAppearance 不会覆盖主题数据
android:actionBarStyle 需要 API 级别 11
在 Android Studio 的 build.gradle 中设置的 Android R/11 的 API 级别是啥?