Flutter - 如果日期相同(今天),DatePicker 不会打开

Flutter - DatePicker is not opening if it is same date(today)

我想在我的日历中只启用每周的周五。如果它不是同一日期它正在工作,即如果当天不是星期五那么它正在工作,否则如果我试图在星期五打开日历,那么我会遇到异常。

[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: 'package:flutter/src/material/date_picker.dart': Failed assertion: line 1147 pos 5: 'selectableDayPredicate == null || selectableDayPredicate(initialDate)': Provided initialDate must satisfy provided selectableDayPredicate

下面是我正在使用的代码。

DateTime selectedDate = DateTime.now();

    bool defineSelectable(DateTime val) {
      DateTime now = DateTime.now();
      // disabled all days before today
      if (val.isBefore(now)) {
        return false;
      }
      // disabled all days except Friday
      switch (val.weekday) {
        case DateTime.friday:
          return true;
          break;
        default:
          return false;
      }
    }

    int daysToAdd(int todayIndex, int targetIndex) {
      print('todayIndex $todayIndex');
      print('targetIndex $targetIndex');
      if (todayIndex < targetIndex) { // jump to target day in same week
        return targetIndex - todayIndex;
      } else if (todayIndex > targetIndex) { // must jump to next week
        return 7 + targetIndex - todayIndex;
      } else {
        return 0; // date is matched
      }
    }

    DateTime defineInitialDate() {
      DateTime now = DateTime.now();
      int dayOffset = daysToAdd(now.weekday, DateTime.friday);
      print('dayOffset: $dayOffset');
      return now.add(Duration(days: dayOffset));
    }

    Future<Null> _selectDate(BuildContext context) async {
      print('defineInitialDate: ${defineInitialDate()}');
      print('defineSelectable: $defineSelectable');
      final DateTime picked = await showDatePicker(
          context: context,
          initialDate: defineInitialDate(),
          selectableDayPredicate: defineSelectable,
          firstDate: DateTime(2018, 12),
          lastDate: DateTime(2020, 12));
      if (picked != null && picked != selectedDate) selectedDate = picked;
      var formatter = DateFormat('EEEE, dd-MMMM-yyyy');
      String formatted = formatter.format(selectedDate);
      print('Select Date: $formatted');
      _askGiveProvider.meetingSink(formatted);
      //addEventBloc.eventDateSink(formatted);
    }

不确定到底是什么问题。如果你能告诉我我需要更新什么才能得到这个,那就太好了。

而且我还想从当前日期起仅启用 2 周。我怎样才能做到这一点?

谢谢。

这是解决方案 您需要在传递的 initialDate 上使 defineSelectable function return 为真。请参阅下面的工作代码

DateTime selectedDate = DateTime.now();
DateTime initialData;

bool defineSelectable(DateTime val) {
DateTime now = DateTime.now();
//make it return true on initialDate
if(val.compareTo(initialData)==0){
return true;
}
// disabled all days before today
if (val.isBefore(now)) {
return false;
}
// disabled all days except Friday
switch (val.weekday) {
case DateTime.friday:
  return true;
  break;
default:
  return false;
}
}

int daysToAdd(int todayIndex, int targetIndex) {
print('todayIndex $todayIndex');
print('targetIndex $targetIndex');
if (todayIndex < targetIndex) { // jump to target day in same 
week
return targetIndex - todayIndex;
} else if (todayIndex > targetIndex) { // must jump to next 
week
return 7 + targetIndex - todayIndex;
} else {
return 0; // date is matched
}
}

DateTime defineInitialDate() {
DateTime now = DateTime.now();
int dayOffset = daysToAdd(now.weekday, DateTime.friday);
print('dayOffset: $dayOffset');
return now.add(Duration(days: dayOffset));
}

Future<Null> _selectDate(BuildContext context) async {
initialData = defineInitialDate();
print('defineInitialDate: ${initialData}');
print('defineSelectable: $defineSelectable');
final DateTime picked = await showDatePicker(
  context: context,
  initialDate: initialData,
  selectableDayPredicate: defineSelectable,
  firstDate: DateTime(2018, 12),
  lastDate: DateTime(2020, 12));
if (picked != null && picked != selectedDate) selectedDate = 
picked;
//var formatter = DateFormat('EEEE, dd-MMMM-yyyy');
//String formatted = formatter.format(selectedDate);
print('Select Date: $selectedDate');
//_askGiveProvider.meetingSink(formatted);
//addEventBloc.eventDateSink(formatted);
}

试试这个, 这不会在更改日期后禁用今天的日期

  DateTime selectedDate = DateTime.now();
  DateTime initialData;

  bool defineSelectable(DateTime val) {
    DateTime now = DateTime.now();
    // disabled all days except Friday
    switch (val.weekday) {
      case DateTime.friday:
        return true;
        break;
      default:
        return false;
    }

  }

  int daysToAdd(int todayIndex, int targetIndex) {
    print('todayIndex $todayIndex');
    print('targetIndex $targetIndex');
    if (todayIndex < targetIndex) { // jump to target day in same week
      return targetIndex - todayIndex ;
    } else if (todayIndex > targetIndex) { // must jump to next week
      return 7 + targetIndex - todayIndex ;
    } else {
      return 0; // date is matched
    }
  }

  DateTime defineInitialDate() {
    DateTime now = DateTime.now();
    int dayOffset = daysToAdd(now.weekday, DateTime.friday);
    print('dayOffset: $dayOffset');
    return now.add(Duration(days: dayOffset));
  }

  Future<Null> _selectDate(BuildContext context) async {
    initialData = defineInitialDate();
    print('defineInitialDate: ${defineInitialDate()}');
    print('defineSelectable: $defineSelectable');
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: initialData,
        selectableDayPredicate: defineSelectable,
        firstDate: DateTime(2018, 12),
        lastDate: DateTime(defineInitialDate().year,defineInitialDate().month, defineInitialDate().day+14));
    if (picked != null && picked != selectedDate) selectedDate = picked;
    var formatter = DateFormat('EEEE, dd-MMMM-yyyy');
    String formatted = formatter.format(selectedDate);
    print('Select Date: $formatted');
//    _askGiveProvider.meetingSink(formatted);
    //addEventBloc.eventDateSink(formatted);
  }