使用存储在变量中的列表值索引会出错,而直接使用列表值可以正常工作 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
要么在小部件树中的某处插入一个构建器,要么更好地将构建功能拆分为多个小部件。这也将使您的代码更易于阅读。
在我的屏幕上,我在半个屏幕上有一个 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
要么在小部件树中的某处插入一个构建器,要么更好地将构建功能拆分为多个小部件。这也将使您的代码更易于阅读。