【问题标题】:How to disable list of specific date on flutter如何在颤动上禁用特定日期列表
【发布时间】:2019-05-07 22:41:32
【问题描述】:

我有一个调用 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,
                            );
                          }

【问题讨论】:

    标签: dart flutter flutter-dependencies


    【解决方案1】:

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

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

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

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

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

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

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

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

    重要的是你有一组字符串而不是一个列表,因为 selectableDayPredicate 会运行很多次,如果你每次都遍历整个不可选择的日期列表(这就是 List 的 contains确实),它可能会变慢,因为它是 O(n*m) 其中 n 是检查的日期数,m 是不可选择的日期数 - 而如果你使用一个集合,contains 使用更有效的哈希计算然后查找导致O(n)。这可以理解为过早的优化,但在这种情况下,我认为这是值得的。

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

    class .... {
      Set<String> unselectableDates; // assuming this is set somewhere
    
      ....
        onTap: () {
          showDatePicker(
            ...
            selectableDayPredicate: (DateTime val) {
              String sanitized = sanitizeDateTime(val);
              return !unselectableDates.contains(sanitized);
            }
        }
    }
    

    【讨论】:

    • @rmtmckenzre 感谢您的出色回答。正是我想要的!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-09
    • 2020-12-25
    相关资源
    最近更新 更多