gpt4 book ai didi

android - 在 DatePicker 上设置 MinDate 会将 CalendarView 移动到 1964

转载 作者:IT老高 更新时间:2023-10-28 23:40:03 26 4
gpt4 key购买 nike

我正在调试一个问题,如果设置了非默认最小日期,则 DatePicker 中的 CalendarView 会移动到 1964 年 10 月。这至少在 API17 Nexus7 模拟器上重现,但在平台样式包括日期选择器中的微调器和日历 View 的其他设备上也有关于此问题的报告。

这是一个演示问题的代码 fragment :

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

...

new DatePickerDialog1964(context).show();

屏幕截图:

October 1964 calendar view in date picker

当然,期望是微调器和日历 View 将显示相同的日期。

我会继续调试,但如果任何 SO 用户有经验或其他见解,请分享。

相关:

最佳答案

TL;DR

不是 1964 而是 2100 格式错误。 CalendarView有错误。 formatDateRange()在 2038 年之后无法使用。

解决方法 #1

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

我实际使用的解决方法 #2

// Calendar view is a cascade of bugs.
// Work around that by explicitly disabling it.
datePicker.setCalendarViewShown(false);

分析

CalendarView使用 android.text.format.DateUtils.formatDateRange()用于在标题中生成月/年名称。日历 View 仅在月份编号更改时更新标题。例如,如果月份编号相同但年份发生变化,则表头不会更新。

在布局阶段的某个地方,底层的 ListView调用 OnScrollListener在日历 View 上,就像列表滚动到末尾一样。如果月份数改变,则使用上面的测试代码更新表头,将毫秒值传递给 formatDateRange()4131043200000这是在 2100 年末的某个地方,而 2100 是 DatePicker 的默认最大值.

formatDateRange()反过来使用 android.text.format.Time作为其内部日历表示,特别是使用其 set() 设置毫秒方法。我没有检查底层的 native 代码,但我有根据的猜测是传递的毫秒值被截断为 32 位 time_t具有固有 Year 2038 problem 的秒值, 包装到 62 年多一点的值(value)。 Time本身正在使用 struct tm表示年份为 int自 1900 年以来,因此产生了 Time在 1960 年代,然后在标题中格式化。

这可以用普通的 DatePicker 复制。与 CalendarView没有设置最小日期。只需使用微调器将年份移动到 2038 年或更晚,更改月份(以触发标题更新),您就会看到标题换行中的年份为 1902。

现在,问题仍然是为什么设置最小日期会使日历 View 滚动到最大日期。答案似乎是日历 View 的一周 ListView适配器。它索引从最小日期开始的周数,但是当最小日期更改时,适配器的 notifyDataSetChanged()不叫。所以上面的解决方法 #1 有效,因为:

  • 将日期更改超过一个月会使月份标题更改。
  • 更改一周的第一天会使周 ListView 注意到其适配器的数据已更改。

关于android - 在 DatePicker 上设置 MinDate 会将 CalendarView 移动到 1964,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16664562/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com