MaterialDatePicker 显示当前日期而不是需要
Posted
技术标签:
【中文标题】MaterialDatePicker 显示当前日期而不是需要【英文标题】:MaterialDatePicker shows current date instead of needed 【发布时间】:2020-08-22 23:52:23 【问题描述】:使用MaterialDatePicker 我想显示所需的日期并有机会选择另一个。但是当出现 DatePicker 时,它会显示当前日期而不是指定日期。
我插入库:implementation 'com.google.android.material:material:1.2.0-alpha06'
(或 1.1.0)。
然后在styles.xml
中覆盖AppTheme
:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
现在可以显示 DatePicker。
val now = Calendar.getInstance()
now[Calendar.YEAR] = 2020
now[Calendar.MONTH] = 10
now[Calendar.DAY_OF_MONTH] = 1
val builder = MaterialDatePicker.Builder.datePicker()
builder.setSelection(now.timeInMillis)
val picker = builder.build()
fragmentManager?.let picker.show(it, MaterialDatePicker::class.java.simpleName)
这是一个结果。我想显示 11 月 1 日,但显示的是 5 月 7 日。
更新 1
如上链接所述,我们可以使用CalendarConstraints.Builder
:
...
val constraintsBuilder = CalendarConstraints.Builder()
constraintsBuilder.setStart(now.timeInMillis)
constraintsBuilder.setEnd(now.timeInMillis)
val builder = MaterialDatePicker.Builder.datePicker()
builder.setCalendarConstraints(constraintsBuilder.build())
builder.setSelection(now.timeInMillis)
...
这将显示所需的日期,我们可以选择另一天,但我们不能滚动月份。
更新 2
我想这是一个新的 Android DatePicker 的错误。所以我必须选择知名库https://github.com/wdullaer/MaterialDateTimePicker。它选择正确的指定日期,并且不需要更改原始主题。
【问题讨论】:
您需要阅读 ConstrainBuilder 的工作原理。开始/结束是自 Epoch 表示时间瞬间以来的毫秒数,其中包含您感兴趣的“MONTH”显示为开始或结束。setSelection
是一样的,只是表示选择了哪个值,并不代表选择器会打开哪个值。这就是openAt
的用途。您始终必须记住,自 Epoch 以来您需要毫秒。您无法知道自一个日期以来经过了多少 MS,您需要一个 ZonedDateTime。
setStart/End 有效地停止显示之前和之后的月份。这就是它所做的一切。如果您知道想要某个“月份”之间的日期,它可以节省您的验证。日部分(据我所知)完全被忽略(但在以后的修订版中可能已经改变)。请参阅下面加布里埃尔的回答。这是使用 Java 8(或 ThreeTenABP,如果您无权访问 Gradle 4.x 和/或 API 26++,因此无法访问 Java 8 时间。* api)的正确方法
我的意思是:你在这里责备错误的主题。 Material Date Picker 是一个 UX 垃圾,但它可以工作。您拥有的“知名库”还可以,但绝对不需要它,并且它会遇到完全相同的问题和可发现性噩梦,因为它是 Material Design 实现的“副本”,以及许多其他间距、高度、等等。所以,这是一样的废话:)
@MartinMarconcini,我为你鼓掌! :) 非常有趣的叙述。您的体验很棒!
谢谢。我很高兴它有服务。我会写一个答案,但现有的答案是绝对有效的。我只是想确保您了解正在发生的事情以及为什么需要“分区”当地时间来获得其“时间”,这是日历约束使用的......一个非常奇怪的决定,但这是 Android,如果事情不能被打磨,它们无论如何都会被发布,并且可能会在 3 年后出现新的“酷”模式时被打磨。 :) 选择一个不错的日期,并确保在您的用户无法弄清楚如何在不滚动的情况下更改年份时让 Google 知道;)
【参考方案1】:
您可以使用 constraintsBuilder.setOpenAt()
方法设置选择器打开的月份。
如果在边界内,则默认值为当前月份,否则为边界内最早的月份:
CalendarConstraints.Builder constraintsBuilder = new CalendarConstraints.Builder();
LocalDateTime local = LocalDateTime.of(2020, 11, 1, 0, 0);
long openAt= local.atZone(ZoneId.ofOffset("UTC", ZoneOffset.UTC)).toInstant().toEpochMilli();
//you can also use Calendar.getInstance()...
constraintsBuilder.setOpenAt(openAt);
builder.setCalendarConstraints(constraintsBuilder.build());
您可以通过以下方式设置默认选择(默认为无选择):
builder.setSelection(....);
【讨论】:
今天不工作。这很奇怪 @Vlad,这很奇怪。我启动了一个应用程序,它显示了所需的日期(甚至是 2000 年),请参阅pastebin.com/CiVJgJUP。以上是关于MaterialDatePicker 显示当前日期而不是需要的主要内容,如果未能解决你的问题,请参考以下文章
MaterialDatePicker,选择结束日期后应用程序崩溃
MaterialDatePicker 选择后返回不正确的日期
如何在 MaterialDatePicker 中禁用过去的日期?