如何禁用颤振上的特定日期列表

RIF*_*FAL 4 dart flutter flutter-dependencies

我有一个调用 showDatePicker 的代码,我的问题是如何禁用特定日期、一个、两个或多个 json 日期的列表?我尝试禁用周六和周日的 selectableDayPredicate,但是如何禁用来自 api 的 json 日期列表?

                onTap: () {
                            showDatePicker(
                              context: context,
                              initialDate:
                                  DateTime.now().add(Duration(days: 2)),
                              firstDate:
                                  DateTime.now().add(Duration(days: 1)),
                              lastDate:
                                  DateTime.now().add(Duration(days: 730)),
                              selectableDayPredicate: (DateTime val) =>
                                  val.weekday == 5 || val.weekday == 6
                                      ? false
                                      : true,
                            );
                          }
Run Code Online (Sandbox Code Playgroud)

rmt*_*zie 10

这在很大程度上取决于您从 API 获得的数据。我帮不了你,但我可以。

假设你已经从你的服务器中检索了一个包含一堆字符串的 json 列表,将它们解析为 DateTime 对象(可能使用类似 DateTime.parse 的东西),那么它相对简单。

基本上,您需要检查每个日期(使用 selectableDayPredicate),如果它不在您的列表中,则返回 true。

首先,您需要清理 DateTime 对象,因为它们可能包含小时、秒、毫秒等。并且您需要将它们设置为可以快速搜索的格式 - 所以可能不是 DateTime。DateTimes 在技术上可以工作,因为它们确实有 hashCode 实现,但是您必须创建新的 DateTime 对象,这些对象无论如何都只包含年、月和日(因为 +1 毫秒的日期时间在技术上与没有它的日期时间值不同)。如果您真的想这样做,您可以更改sanitizeDateTime下面的函数以返回 aDateTimegetDateSet返回 a Set<DateTime>,但我建议将它们制作成字符串,因为它们在集合中运行良好并且很简单。

所以你需要一个类似的函数:

String sanitizeDateTime(DateTime dateTime) => "${dateTime.year}-${dateTime.month}-${dateTime.day}";

无论你在哪里得到你的 json,你都会想要使用它来格式化它并将它插入到一个集合中。

Set<String> getDateSet(List<DateTime> dates) => dates.map(sanitizeDateTime).toSet();

重要的是你有一个字符串集而不是一个列表,因为 selectableDayPredicate 会运行很多次,如果你每次都迭代整个不可选择的日期列表(这就是 Listcontains所做的),它可能会得到慢,因为它是O(n*m)在那里n是被检查的日期数和m是不可选择的日期数量-而如果你使用一组,contains使用了更高效的散列计算,然后查找其结果O(n)。这可能被解释为过早优化,但在这种情况下,我认为这是值得的。

一旦您拥有一组不可选择的日期,您只需在谓词中检查它们。

IE

class .... {
  Set<String> unselectableDates; // assuming this is set somewhere

  ....
    onTap: () {
      showDatePicker(
        ...
        selectableDayPredicate: (DateTime val) {
          String sanitized = sanitizeDateTime(val);
          return !unselectableDates.contains(sanitized);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)