使用存储在变量中的列表值索引会出错,而直接使用列表值可以正常工作 Flutter

Using a List value index stored in a variable trows an error while using List value directly works fine Flutter

在我的屏幕上,我在半个屏幕上有一个 ListView,它显示了存储在 List<Booking> bookings 中的本地数据库的所有预订记录,在另一半屏幕上,我有一个详细视图从 ListView 中选择的预订项目。 在详细视图中,我还有 3 个按钮,用于将推送通知事件发送到将预订作为输入参数的 bloc。 为了能够引用详细信息视图中显示的预订,我在从 ListView 中选择项目时将 ListView 项目索引存储在 int selectedBooking = 0; 变量中。 问题是使用该变量从按钮发送通知事件会引发错误。我尝试直接从 ListView 项目选择发送它,它发送得很好。 我确定它不为 null,因为我在发送通知之前打印 bookings[selectedBooking] 并且打印正常,但是一些如何使通知发送事件抛出一个错误,该错误不会在 catch 范围内打印。

唯一不同的是,在ListView项目的onTap:我直接预订了List<Booking>booking[index],而在按钮的onPressed:我使用存储相同索引的变量 bookings[selectedBooking]..

这是屏幕构建:

Widget build(BuildContext context) {
    return MultiBlocProvider(
        providers: [
          BlocProvider<BookingBloc>(
            create: (context) =>
                BookingBloc(widget.user)..add(LoadBookings(user: widget.user)),
          ),
          BlocProvider<PushNotificationBloc>(
            create: (context) => PushNotificationBloc(),
          ),
        ],
        child: MultiBlocListener(
          listeners: [
            BlocListener<BookingBloc, BookingState>(
                listener: (BuildContext context, BookingState state) {
              if (state is LoadedBookings) {
                setState(() {
                  bookings = state.bookings;
//                  isSelected = state.isSelected;
//                  Timer(Duration(milliseconds: 50), () {
//                    scrollToIndex(bookings);
//                  });
                });
              }
              if (state is BookingDetails) {
                setState(() {
                  bookingId = state.booking.bookingId;
                  bookingDate = dateOnlyFormat.format(
                      DateTime.fromMillisecondsSinceEpoch(
                          state.booking.bookingStart));
                  bookingStart = timeFormat.format(
                      DateTime.fromMillisecondsSinceEpoch(
                          state.booking.bookingStart));
                  bookingEnd = timeFormat.format(
                      DateTime.fromMillisecondsSinceEpoch(
                          state.booking.bookingEnd));
                  customerName = state.booking.customerName;
                  works = state.booking.worksNameList;
                  bookingPrice = state.booking.bookingPrice;
                  collectedOnDate = state.booking.collectedOnDate;
                });
              }
            }),
          ],
          child: Container(

这是 ListView 项的 onTap:

onTap: () {
  // sending push here does work...
  //BlocProvider.of<PushNotificationBloc>(
  //context).add(
  //BookingStartedPushNotification(
  //booking: bookings[index]));
  if (isSelected[index] == false) {
    //store booking in a variable for sending notifications
    selectedBooking = index;
    print(
      'selected booking is ${bookings[selectedBooking].toMap().toString()}');
    //load selected booking
    BlocProvider.of<BookingBloc>(context).add(
      LoadBookingDetails(
        DateTime.fromMillisecondsSinceEpoch(
          bookings[index].bookingStart),
      ),
    );
  } else {
    setState(() {
      //selectedBooking = null;
      print(
        'selected booking is ${bookings[selectedBooking].toMap().toString()}');
      bookingId = '';
      bookingDate = '';
      bookingStart = '';
      bookingEnd = '';
      customerName = '';
      works = '';
      bookingPrice = '';
      bookingState = '';
      collectedOnDate = '';
    });
  }
setState(() {
  //invert isSelected value
  isSelected[index] = !isSelected[index];
}

这是按下按钮:

onPressed: () {
  print("Started button is been clicked");
  //cache.play(
  //'tableViewClose.mp3');
  print(
    'selected booking is : ${bookings[selectedBooking].toMap().toString()}');
  try {
    BlocProvider.of<PushNotificationBloc>(
      context)
    .add(BookingStartedPushNotification(
      booking:
      bookings[selectedBooking]));
  } catch (e) {
    print('Error is : $e');
  }

  BlocProvider.of<BookingBloc>(context).add(
    UpdateBookingState(
    user: widget.user,
    cityDb: widget.cityDb,
    regionDb: widget.regionDb,
    booking:
    bookings[selectedBooking],
    state: 'Started'));
}

您在按钮 onPressed 中的上下文可能没有可用的 PushNotificationBloc 或 BookingBloc。您的小部件树位于一个大型构建方法中,永远不会被构建器打断。 所以 onPressed 方法中使用的上下文是通过顶部 Widget build(BuildContext context) 传递的上下文,它没有 MultiBlocProvider 作为祖先。

看看 BlocProvider.of() 在此处找不到 Bloc 部分: https://bloclibrary.dev/#/faqs

要么在小部件树中的某处插入一个构建器,要么更好地将构建功能拆分为多个小部件。这也将使您的代码更易于阅读。