在屏幕上,我有一个ScrollablePositionedList.builder
,并且我正在使用slidable
进行幻灯片删除db中的记录,我弹出一个显示确认对话框,在用户确认删除后,我想显示小吃吧。在添加确认对话框之前,小吃栏显示为正常,但是现在我得到了Scaffold.of() called with a context that does not contain a Scaffold
。我需要在显示该对话框以关闭确认对话框之前调用Navigator.pop(context)
,以为这是我尝试发表评论的原因它出来,但我仍然得到错误。
您能在这里发现我做错了吗?我还想展示在BookingDeleted
中进入BlocLister
状态的小吃店,如何实现它,因为它在Scaffold
树之前?
和往常一样,非常感谢您的帮助。
这是屏幕代码:
class _BookingsScreenState extends State<BookingsScreen> {
dynamic backButton = Platform.isIOS ? CupertinoIcons.back : Icons.arrow_back;
DateFormat dateOnlyFormat =
DateFormat.yMMMMEEEEd(AppLocalizations.instance.text('Language code'));
DateFormat timeFormat = DateFormat('Hm');
AudioCache cache = new AudioCache();
ItemScrollController scrollController = ItemScrollController();
List<Booking> bookings = [];
int cellIndex = 0;
@override
Widget build(BuildContext context) {
cache.loadAll(['click.mp3', 'tableViewOpen.mp3', 'tableViewClose.mp3']);
return BlocListener<BookingBloc, BookingState>(
listener: (BuildContext context, BookingState state) {
if (state is LoadedBookings) {
setState(() {
bookings = state.bookings;
print(
'BookingsScreen BlocListener we have ${state.bookings.length} saved bookings');
print(
'BookingsScreen BlocListener saved bookings are ${state.bookings}');
print(bookings);
});
}
if (state is BookingDeleted) {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return BookingDeletedConfirmationDialog();
}
);
Timer(Duration(milliseconds: 1500), (){
cache.play('tableViewClose.mp3');
Navigator.of(context, rootNavigator: false).pop(context);
});
}
},
child: Stack(
children: [
Image(
image: widget.bgImage.image,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover),
Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
elevation: 0,
centerTitle: true,
leading: IconButton(
icon: Icon(backButton),
color: Colors.redAccent,
onPressed: () {
cache.play('tableViewClose.mp3');
Navigator.pop(context);
}),
title: Text(
AppLocalizations.instance.text('BookingScreenTitle'),
style: TextStyle(
color: Colors.orange,
fontSize: 22,
fontWeight: FontWeight.w500,
letterSpacing: 1),
),
backgroundColor: Colors.transparent,
),
body: SafeArea(
minimum: EdgeInsets.symmetric(horizontal: 20),
child: ScrollablePositionedList.builder(
itemScrollController: scrollController,
itemCount: bookings.length,
itemBuilder: (BuildContext context, int index) => Slidable(
actionPane: SlidableBehindActionPane(),
actionExtentRatio: 0.25,
actions: <Widget>[
IconSlideAction(
caption:
AppLocalizations.instance.text('Booking details'),
color: Colors.transparent,
foregroundColor: Colors.blue,
icon: Icons.details,
onTap: () {
print('BookingDetailsScreen');
},
),
],
secondaryActions: <Widget>[
IconSlideAction(
caption: AppLocalizations.instance.text('Delete booking'),
color: Colors.transparent,
foregroundColor: Colors.red,
icon: Icons.delete,
onTap: () {
setState(() {
cellIndex = index;
});
var booking = bookings.elementAt(index);
if (booking.bookingState == 'Waiting' || booking.bookingState == 'Received' || booking.bookingState == 'Cancelled') {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return BookingDeletionConfirmationDialog(
index: index,
booking: booking,
onPressedCancel: (){
cache.play('tableViewClose.mp3');
Navigator.pop(context);
},
onPressedDelete: (){
cache.play('tableViewClose.mp3');
Navigator.pop(context);
deleteItem(index, booking);
//Scaffold.of() called with a context that does not contain a Scaffold. ???
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.redAccent,
content: Text(
AppLocalizations.instance
.text('Booking deleted'),
style: TextStyle(color: Colors.white),
),
action: SnackBarAction(
textColor: Colors.white,
label: AppLocalizations.instance.text('Undo'),
onPressed: () {
//To undo deletion
undoDeletion(index, booking);
})));
},
);
}
);
} else {
Scaffold.of(context).showSnackBar(SnackBar(
backgroundColor: Colors.redAccent,
content: Text(
AppLocalizations.instance
.text('Booking not deletable'),
style: TextStyle(color: Colors.white),
),
));
}
},
),
],
child: BookingCell(
isSelected: false,
borderColor: bookings[index].bookingState == 'Waiting'
? Colors.blue
: bookings[index].bookingState == 'Received'
? Colors.amber.shade200
: bookings[index].bookingState == 'Started'
? Colors.amber.shade600
: bookings[index].bookingState == 'Completed'
? Colors.green.shade400
: bookings[index].bookingState ==
'Cancelled'
? Colors.redAccent
: Colors.blueGrey.shade300,
worksList: bookings[index].worksNameList,
bookingId: bookings[index].bookingId.toString(),
bookingDate: dateOnlyFormat.format(
DateTime.fromMillisecondsSinceEpoch(
bookings[index].bookingDate)),
bookingStart: timeFormat.format(
DateTime.fromMillisecondsSinceEpoch(
bookings[index].bookingStart)),
shopName: bookings[index].shopName,
),
),
),
),
),
],
),
);
}
void deleteItem(index, Booking booking) {
setState(() {
BlocProvider.of<BookingBloc>(context).add(DeleteBooking(
booking: booking,
cityDb: widget.cityDb,
regionDb: widget.regionDb,
countryDb: widget.countryDb));
});
BlocProvider.of<BookingBloc>(context).add(UpdateBookingState(
bookingId: booking.bookingId.toString(), state: 'Cancelled'));
}
void undoDeletion(index, Booking booking) {
setState(() {
booking.bookingState ='Reactivated.'+ booking.bookingState;
BlocProvider.of<BookingBloc>(context).add(SaveBooking(
booking: booking,
cityDb: widget.cityDb,
regionDb: widget.regionDb,
countryDb: widget.countryDb));
});
}
}
答案 0 :(得分:0)
尝试使用脚手架全局密钥的此解决方案
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class _BookingsScreenState extends State<BookingsScreen> {
dynamic backButton = Platform.isIOS ? CupertinoIcons.back : Icons.arrow_back;
DateFormat dateOnlyFormat =
DateFormat.yMMMMEEEEd(AppLocalizations.instance.text('Language code'));
DateFormat timeFormat = DateFormat('Hm');
AudioCache cache = new AudioCache();
ItemScrollController scrollController = ItemScrollController();
List<Booking> bookings = [];
int cellIndex = 0;
// scaffold global key
GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
cache.loadAll(['click.mp3', 'tableViewOpen.mp3', 'tableViewClose.mp3']);
return BlocListener<BookingBloc, BookingState>(
listener: (BuildContext context, BookingState state) {
if (state is LoadedBookings) {
setState(() {
bookings = state.bookings;
print(
'BookingsScreen BlocListener we have ${state.bookings.length} saved bookings');
print(
'BookingsScreen BlocListener saved bookings are ${state.bookings}');
print(bookings);
});
}
if (state is BookingDeleted) {
showDialog(
barrierDismissible: false,
context: context,
builder: (BuildContext context) {
return BookingDeletedConfirmationDialog();
});
Timer(Duration(milliseconds: 1500), () {
cache.play('tableViewClose.mp3');
Navigator.of(context, rootNavigator: false).pop(context);
});
}
},
child: Stack(
children: [
Image(
image: widget.bgImage.image,
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover),
Scaffold(
// assign the key
key: scaffoldKey,
backgroundColor: Colors.transparent,
appBar: AppBar(
elevation: 0,
centerTitle: true,
leading: IconButton(
icon: Icon(backButton),
color: Colors.redAccent,
onPressed: () {
cache.play('tableViewClose.mp3');
Navigator.pop(context);
}),
title: Text(
AppLocalizations.instance.text('BookingScreenTitle'),
style: TextStyle(
color: Colors.orange,
fontSize: 22,
fontWeight: FontWeight.w500,
letterSpacing: 1),
),
backgroundColor: Colors.transparent,
),
body: SafeArea(
minimum: EdgeInsets.symmetric(horizontal: 20),
child: ScrollablePositionedList.builder(
itemScrollController: scrollController,
itemCount: bookings.length,
itemBuilder: (BuildContext context, int index) => Slidable(
actionPane: SlidableBehindActionPane(),
actionExtentRatio: 0.25,
actions: <Widget>[
IconSlideAction(
caption:
AppLocalizations.instance.text('Booking details'),
color: Colors.transparent,
foregroundColor: Colors.blue,
icon: Icons.details,
onTap: () {
print('BookingDetailsScreen');
},
),
],
secondaryActions: <Widget>[
IconSlideAction(
caption: AppLocalizations.instance.text('Delete booking'),
color: Colors.transparent,
foregroundColor: Colors.red,
icon: Icons.delete,
onTap: () {
setState(() {
cellIndex = index;
});
var booking = bookings.elementAt(index);
if (booking.bookingState == 'Waiting' ||
booking.bookingState == 'Received' ||
booking.bookingState == 'Cancelled') {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return BookingDeletionConfirmationDialog(
index: index,
booking: booking,
onPressedCancel: () {
cache.play('tableViewClose.mp3');
Navigator.pop(context);
},
onPressedDelete: () {
cache.play('tableViewClose.mp3');
Navigator.pop(context);
deleteItem(index, booking);
//Scaffold.of() called with a context that does not contain a Scaffold. ???
scaffoldKey.currentState.showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text(
AppLocalizations.instance
.text('Booking deleted'),
style: TextStyle(
color: Colors.white),
),
action: SnackBarAction(
textColor: Colors.white,
label: AppLocalizations.instance
.text('Undo'),
onPressed: () {
//To undo deletion
undoDeletion(index, booking);
})));
},
);
});
} else {
scaffoldKey.currentState.showSnackBar(SnackBar(
backgroundColor: Colors.redAccent,
content: Text(
AppLocalizations.instance
.text('Booking not deletable'),
style: TextStyle(color: Colors.white),
),
));
}
},
),
],
child: BookingCell(
isSelected: false,
borderColor: bookings[index].bookingState == 'Waiting'
? Colors.blue
: bookings[index].bookingState == 'Received'
? Colors.amber.shade200
: bookings[index].bookingState == 'Started'
? Colors.amber.shade600
: bookings[index].bookingState == 'Completed'
? Colors.green.shade400
: bookings[index].bookingState ==
'Cancelled'
? Colors.redAccent
: Colors.blueGrey.shade300,
worksList: bookings[index].worksNameList,
bookingId: bookings[index].bookingId.toString(),
bookingDate: dateOnlyFormat.format(
DateTime.fromMillisecondsSinceEpoch(
bookings[index].bookingDate)),
bookingStart: timeFormat.format(
DateTime.fromMillisecondsSinceEpoch(
bookings[index].bookingStart)),
shopName: bookings[index].shopName,
),
),
),
),
),
],
),
);
}
void deleteItem(index, Booking booking) {
setState(() {
BlocProvider.of<BookingBloc>(context).add(DeleteBooking(
booking: booking,
cityDb: widget.cityDb,
regionDb: widget.regionDb,
countryDb: widget.countryDb));
});
BlocProvider.of<BookingBloc>(context).add(UpdateBookingState(
bookingId: booking.bookingId.toString(), state: 'Cancelled'));
}
void undoDeletion(index, Booking booking) {
setState(() {
booking.bookingState = 'Reactivated.' + booking.bookingState;
BlocProvider.of<BookingBloc>(context).add(SaveBooking(
booking: booking,
cityDb: widget.cityDb,
regionDb: widget.regionDb,
countryDb: widget.countryDb));
});
}
}