laa*_*lto 15 android android-datepicker
我正在调试一个问题,如果设置了非默认的最小日期CalendarView,那么DatePicker移动到1964年10月.这至少在API17 Nexus7仿真器上再现,但在其他设备上有关于此问题的报告,其中平台样式包括日期选择器中的微调器和日历视图.
这是一个演示此问题的代码段:
class DatePickerDialog1964 extends DatePickerDialog {
DatePickerDialog1964(Context c) {
super(c, null, 2013, 4, 21);
@SuppressWarnings("deprecation")
Date min = new Date(2013-1900, 4, 21);
DatePicker p = getDatePicker();
p.setMinDate(min.getTime());
}
}
Run Code Online (Sandbox Code Playgroud)
...
new DatePickerDialog1964(context).show();
Run Code Online (Sandbox Code Playgroud)
截屏:

当然,期望旋转器和日历视图显示相同的日期.
我会继续调试这个,但如果有SO用户有经验或其他见解,请分享.
有关:
laa*_*lto 19
这不是1964年,但2100格式严重.CalendarView有虫子.formatDateRange()在2038年之后不起作用.
class DatePickerDialog1964 extends DatePickerDialog {
DatePickerDialog1964(Context c) {
super(c, null, 2013, 4, 21);
@SuppressWarnings("deprecation")
Date min = new Date(2013-1900, 4, 21);
DatePicker p = getDatePicker();
CalendarView cv = p.getCalendarView(); // should check for null
long cur = cv.getDate();
int d = cv.getFirstDayOfWeek();
p.setMinDate(min.getTime());
cv.setDate(cur + 1000L*60*60*24*40);
cv.setFirstDayOfWeek((d + 1) % 7);
cv.setDate(cur);
cv.setFirstDayOfWeek(d);
}
}
Run Code Online (Sandbox Code Playgroud)
// Calendar view is a cascade of bugs.
// Work around that by explicitly disabling it.
datePicker.setCalendarViewShown(false);
Run Code Online (Sandbox Code Playgroud)
CalendarView使用android.text.format.DateUtils.formatDateRange()在头生产月/年的名字.日历视图仅在月份数更改时更新标题.例如,如果月份编号相同但年份更改,则不更新标题.
在布局阶段的某个地方,底层ListView调用OnScrollListener日历视图,就像列表滚动到最后一样.如果更改了月份编号,则使用上面的测试代码更新标题,传递给的millis值formatDateRange()是41310432000002100年末的某个位置,2100是默认的最大值DatePicker.
formatDateRange()反过来android.text.format.Time用作内部日历表示,特别是使用其set()方法设置毫秒.我没有检查底层的本机代码,但我有根据的猜测是,传入的毫秒值被截断为32位time_t秒值,具有固有的2038年问题,包装到62年以上的值.Time本身就是使用struct tm它代表int自1900 年以来的年份,从而导致在Time20世纪60年代,然后在标题中格式化.
这可以用普通再现DatePicker与CalendarView不分钟日期集.只需使用微调器将年份移动到2038或更高版本,更改月份(触发标题更新),您将看到标题换行中的年份为1902.
现在,问题仍然是为什么设置最小日期会使日历视图滚动到最大日期.答案似乎是日历视图的周ListView适配器.它从最小日期开始索引周数,但是当最小日期更改时,notifyDataSetChanged()不会调用适配器.所以上面的解决方法#1有效,因为:
小智 12
以上答案正是关于这个bug的来源.对于我的应用程序,我正在使用此解决方法:
每次更改DatePicker的日期或minDate时,请使用应在选择器/日历中选择的日期调用以下例程:
private void fixUpDatePickerCalendarView(Calendar date) {
// Workaround for CalendarView bug relating to setMinDate():
// https://code.google.com/p/android/issues/detail?id=42750
// Set then reset the date on the calendar so that it properly
// shows today's date. The choice of 24 months is arbitrary.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
final CalendarView cal = datePicker.getDatePicker().getCalendarView();
if (cal != null) {
date.add(Calendar.MONTH, 24);
cal.setDate(date.getTimeInMillis(), false, true);
date.add(Calendar.MONTH, -24);
cal.setDate(date.getTimeInMillis(), false, true);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我最终使用的解决方案:
private void fixBuggyCalendarview(CalendarView cv) {
long current = cv.getDate();
cv.setDate(cv.getMaxDate(), false, true);
cv.setDate(current, false, true);
}
Run Code Online (Sandbox Code Playgroud)
当您为 CalendarView 设置最小/最大日期时,这也适用
| 归档时间: |
|
| 查看次数: |
16111 次 |
| 最近记录: |