显示小吃条抖动时,在不包含Scaffold错误的上下文中调用Scaffold.of

问题描述

在屏幕上,我有一个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'),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'),));
                        }
                      },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,countryDb: widget.countryDb));
    });
  }

}

解决方法

尝试使用脚手架全局密钥的此解决方案

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),),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'),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,countryDb: widget.countryDb));
    });
  }
}

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...