RangeError(索引):无效值:不在0..30范围内,包括-1:Flutter

时间:2020-05-17 15:48:11

标签: listview flutter bloc

ScrollablePositionedList(这是日历)的第一版中出现此错误。

最初,我声明一个空的List<DateTime> calendar = [];,其中填充了带有状态的日期(我正在使用flutter_bloc),并调用一个方法来检查今天的日期是否在列表中并滚动到该索引,否则滚动到索引0(每月的第一天)。

除了Bloc的InitialState为空之外,我有两种不同的状态,一种是TodayDate用于在屏幕加载时在当月构建窗口小部件,另一种是NewDate,用于在日历中更改月份时重新构建窗口小部件。

我仅在收到TodayDate状态时才收到错误消息(请参阅打印1),但是当更改月份时,一切都会按预期进行(请参见打印2和3)。

我无法确定为什么在第一个小部件构建中会抛出错误,因为可用数据与打印3相同。 最初,我认为这可能与InitialState为空有关,但随后TodayDate状态随数据一起出现,应该可以修复错误。此外,打印显示国家交易后的错误。

您能在我的实现中看到任何错误吗? 一如既往,非常感谢您的时间和帮助。


小部件:

Expanded(
//                            child: ListView.builder(
//                            controller: scrollController,
                            child: ScrollablePositionedList.builder(
                              itemScrollController: scrollController,
                              itemCount: calendar.length,
                              itemBuilder: (BuildContext context, int index) =>
                                  CalendarCell(
                                      day: calendarFormat
                                          .format(calendar[index]),
                                      borderColor: isSelectedDay[index] == true
                                          ? Colors.white
                                          : dateCheckIsToday.format(
                                                      calendar[index]) ==
                                                  dateCheckIsToday
                                                      .format(DateTime.now())
                                              ? Colors.greenAccent
                                              : getDayNameShort.format(
                                                          calendar[index]) ==
                                                      'Sun'
                                                  ? Colors.redAccent
                                                  : Colors.orangeAccent,
                                      isSelected: isSelectedDay[index],
                                      onTap: () {
                                        BlocProvider.of<CalendarBloc>(context)
                                            .add(UpdateCalendarSelectedDay(
                                                isSelectedDay, index));
                                        BlocProvider.of<CalendarBloc>(context)
                                            .add(GetOpeningTimeSlots(
                                                weekday:
                                                    '${getDayNameShort.format(calendar[index])}',
                                                date: calendar[index]));
                                      },
                            ),
                            flex: 2,
                          ),

BlocListener:

if (state is TodayDate) {
                  setState(() {
                    displayDate = state.newDate;
                    print(displayDate);
                    calendar = state.calendar;
                    isSelectedDay = state.isSelectedDay;
                    scrollToIndex(
                        calendar); 
// RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
                  });
                }
                if (state is NewDate) {
                  setState(() {
                    displayDate = state.newDate;
                    calendar = state.calendar;
                    isSelectedDay = state.isSelectedDay;
                    scrollToIndex(calendar); // works perfectly
//                    print('calendar is ${state.calendar}');
//                    print('isDaySelectedDay is ${state.isSelectedDay}');
                  });
                }

scrollToIndex方法:

void scrollToIndex(List<DateTime> calendar) {
    print('scrollToIndex called');
    indexToScrollTo = 0;
    for (int index = 0; index < calendar.length; index++) {
      dateCheckIsToday.format(DateTime.now());
      if (dateCheckIsToday.format(calendar[index]) ==
          dateCheckIsToday.format(DateTime.now())) {
        indexToScrollTo = index;
        break;
      }
    }
    print('indexToScrolTo is: $indexToScrollTo');
    scrollController.jumpTo(
        index: indexToScrollTo); //, duration: Duration(seconds: 1));
  }

打印1:TodayDate状态为5月份的实际打印:

flutter: Event is GetMonth : {actual date :2020-05-17 08:08:41.044548}
flutter: Transaction is Transition { currentState: InitialState : { date: 2000-01-01 00:00:00.000, calendar : [], isSelected :[]}, event: GetMonth : {actual date :2020-05-17 08:08:41.044548}, nextState: TodayDate : { date: 2020-05-17 08:08:41.044548, calendar : [2020-05-01 00:00:00.000, 2020-05-02 00:00:00.000, 2020-05-03 00:00:00.000, 2020-05-04 00:00:00.000, 2020-05-05 00:00:00.000, 2020-05-06 00:00:00.000, 2020-05-07 00:00:00.000, 2020-05-08 00:00:00.000, 2020-05-09 00:00:00.000, 2020-05-10 00:00:00.000, 2020-05-11 00:00:00.000, 2020-05-12 00:00:00.000, 2020-05-13 00:00:00.000, 2020-05-14 00:00:00.000, 2020-05-15 00:00:00.000, 2020-05-16 00:00:00.000, 2020-05-17 00:00:00.000, 2020-05-18 00:00:00.000, 2020-05-19 00:00:00.000, 2020-05-20 00:00:00.000, 2020-05-21 00:00:00.000, 2020-05-22 00:00:00.000, 2020-05-23 00:00:00.000, 2020-05-24 00:00:00.000, 2020-05-25 00:00:00.000, 2020-05-26 00:00:00.000, 2020-05-27 00:00:00.000, 2020-05-28 00:00:00.000, 2020-05-29 00:00:00.000, 2020-05-30 00:00:00.0<…>
flutter: 2020-05-17 08:08:41.044548
flutter: scrollToIndex called
flutter: indexToScrolTo is: 16

════════ (4) Exception caught by widgets library ═══════════════════════════════════════════════════
RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
════════════════════════════════════════════════════════════════════════════════════════════════════

打印2:NewDate将月份更改为六月时的状态:

flutter: Event is NextMonth : {actual date :2020-05-17 08:08:41.044548}
flutter: Transaction is Transition { currentState: TodayDate : { date: 2020-05-17 08:08:41.044548, calendar : [2020-05-01 00:00:00.000, 2020-05-02 00:00:00.000, 2020-05-03 00:00:00.000, 2020-05-04 00:00:00.000, 2020-05-05 00:00:00.000, 2020-05-06 00:00:00.000, 2020-05-07 00:00:00.000, 2020-05-08 00:00:00.000, 2020-05-09 00:00:00.000, 2020-05-10 00:00:00.000, 2020-05-11 00:00:00.000, 2020-05-12 00:00:00.000, 2020-05-13 00:00:00.000, 2020-05-14 00:00:00.000, 2020-05-15 00:00:00.000, 2020-05-16 00:00:00.000, 2020-05-17 00:00:00.000, 2020-05-18 00:00:00.000, 2020-05-19 00:00:00.000, 2020-05-20 00:00:00.000, 2020-05-21 00:00:00.000, 2020-05-22 00:00:00.000, 2020-05-23 00:00:00.000, 2020-05-24 00:00:00.000, 2020-05-25 00:00:00.000, 2020-05-26 00:00:00.000, 2020-05-27 00:00:00.000, 2020-05-28 00:00:00.000, 2020-05-29 00:00:00.000, 2020-05-30 00:00:00.000, 2020-05-31 00:00:00.000], isSelected :[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, fals<…>
flutter: scrollToIndex called
flutter: indexToScrolTo is: 0

打印3:NewDate用于将月份更改为5月份的打印:

flutter: Event is PreviousMonth :{actual date :2020-06-17 00:00:00.000}
flutter: Transaction is Transition { currentState: NewDate : { date: 2020-06-17 00:00:00.000, calendar : [2020-06-01 00:00:00.000, 2020-06-02 00:00:00.000, 2020-06-03 00:00:00.000, 2020-06-04 00:00:00.000, 2020-06-05 00:00:00.000, 2020-06-06 00:00:00.000, 2020-06-07 00:00:00.000, 2020-06-08 00:00:00.000, 2020-06-09 00:00:00.000, 2020-06-10 00:00:00.000, 2020-06-11 00:00:00.000, 2020-06-12 00:00:00.000, 2020-06-13 00:00:00.000, 2020-06-14 00:00:00.000, 2020-06-15 00:00:00.000, 2020-06-16 00:00:00.000, 2020-06-17 00:00:00.000, 2020-06-18 00:00:00.000, 2020-06-19 00:00:00.000, 2020-06-20 00:00:00.000, 2020-06-21 00:00:00.000, 2020-06-22 00:00:00.000, 2020-06-23 00:00:00.000, 2020-06-24 00:00:00.000, 2020-06-25 00:00:00.000, 2020-06-26 00:00:00.000, 2020-06-27 00:00:00.000, 2020-06-28 00:00:00.000, 2020-06-29 00:00:00.000, 2020-06-30 00:00:00.000],isSelected :[false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, <…>
flutter: scrollToIndex called
flutter: indexToScrolTo is: 16

如打印所显示的,当更改月份并收到NewDate状态时,小部件正确更新,并且更改回实际月份时,它的行为也符合预期,跳到今天的日期。那么,为什么TodayDate失败了,却承载了相同的数据,并且对滚动方法的调用与NewDate相同?

更新:

使用Timer延迟对scrollToIndex方法的调用使其正常工作。希望这有助于了解问题出在哪里。

if (state is TodayDate) {
                  setState(() {
                    displayDate = state.newDate;
                    print(displayDate);
                    calendar = state.calendar;
                    isSelectedDay = state.isSelectedDay;
                    Timer(Duration(milliseconds: 50), () {
                      scrollToIndex(calendar);
                    });
                    // timer makes it work

// RangeError (index): Invalid value: Not in range 0..30, inclusive: -1
                  });
//                  scrollToIndex(calendar);
                }

0 个答案:

没有答案