简体   繁体   中英

showBottomSheet Scaffold issue with context

Trying to implement showBottomSheet into my app, but it is throwing an error: Scaffold.of() called with a context that does not contain a Scaffold.

After searching the web a bit, I added a GlobalKey but that seems like it is not doing the trick. Does anyone have a suggestion?

class _DashboardState extends State<Dashboard> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();
  int _bottomNavBarCurrentIndex = 0;
  dashboardViews.DashboardView dView = new dashboardViews.DashboardView();

  List<Widget> _listOffers = new List<Widget>();

  Widget _currentView;

  void loadDashboardView() {
    _currentView = (_bottomNavBarCurrentIndex == 0
        ? dView.getOfferView(_listOffers, _getOfferData)
        : dView.getOrdersView());
  }

  _showInfoSheet() {
    showBottomSheet(
                context: _scaffoldKey.currentContext,
                builder: (context) {
                  return Text('Hello');
                });
  }

  Future _getOfferData() async {
    loadDashboardView();

    List<Widget> _resultsOffers = new List<Widget>();

    SharedPreferences prefs = await SharedPreferences.getInstance();
    String _token = prefs.getString('token');

    final responseOffers =
        await http.get(globals.apiConnString + 'GetActiveOffers?token=$_token');

    if (responseOffers.statusCode == 200) {
      List data = json.decode(responseOffers.body);

      for (var i = 0; i < data.length; i++) {       
        _resultsOffers.add(GestureDetector(
            onTap: () => _showInfoSheet(),
            child: Card(
                child: Padding(
                    padding: EdgeInsets.all(15),
                    child: Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: <Widget>[
                          Row(children: <Widget>[
                            Expanded(
                                flex: 5,
                                child: Text('${data[i]['Title']}',
                                    style: TextStyle(
                                        fontWeight: FontWeight.bold,
                                        color: globals.themeColor4))),
                            Expanded(
                                flex: 3,
                                child: Row(children: <Widget>[
                                  Icon(Icons.access_time,
                                      size: 15, color: Colors.grey),
                                  Padding(
                                      padding: EdgeInsets.fromLTRB(5, 0, 10, 0),
                                      child: Text('11:30 PM',
                                          style:
                                              TextStyle(color: Colors.black))),
                                ])),
                            Expanded(
                                flex: 1,
                                child: Row(children: <Widget>[
                                  Icon(Icons.local_dining,
                                      size: 15, color: Colors.grey),
                                  Padding(
                                      padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
                                      child: Text('${i.toString()}',
                                          style:
                                              TextStyle(color: Colors.black))),
                                ])),
                          ]),
                          Padding(padding: EdgeInsets.all(10)),
                          Row(children: <Widget>[
                            Text(
                              'Created May 2, 2019 at 2:31 PM',
                              style: TextStyle(color: Colors.grey[600]),
                              textAlign: TextAlign.start,
                            )
                          ])
                        ])))));
           }       
      }

      setState(() {
        _listOffers = _resultsOffers;
      });

      loadDashboardView();
    }
  }

  void _bottomNavBarTap(int index) {
    setState(() {
      _bottomNavBarCurrentIndex = index;
      loadDashboardView();
    });
  }

  void pullRefresh() {
    _getOfferData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      backgroundColor: Colors.grey[200],
      body: _currentView,
      bottomNavigationBar: BottomNavigationBar(
        onTap: _bottomNavBarTap,
        currentIndex: _bottomNavBarCurrentIndex,
        items: [
          BottomNavigationBarItem(
              icon: Icon(Icons.near_me), title: Text('OFFERS')),
          BottomNavigationBarItem(
              icon: Icon(Icons.broken_image), title: Text('ORDERS'))
        ],
      ),
    );
  }
}

Hope someone can point me in the right direction, thanks!

EDIT: Here is one of the links I looked at with the same problem, and I tried setting the builder context to c as suggested but didn't work: https://github.com/flutter/flutter/issues/23234

EDIT 2: Adding screenshot that shows the variable contents when I'm getting the Scaffold.of() called with a context that does not contain a Scaffold error.

错误截图

The reason you're getting this error is because you're calling Scaffold during its build process, and thus your showBottomSheet function can't see it. A workaround this problem is to provide a stateful widget with a Scaffold , assign the Scaffold a key , and then pass it to your Dashboard (I assumed it is the name of your stateful widget from your state class). You don't need to assign a key to the Scaffold inside the build of _DashboardState .

This is the class where you provide a Scaffold with key :

 class DashboardPage extends StatefulWidget {

  @override
  _DashboardPageState createState() => _DashboardPageState() ;
}

class _DashboardPageState extends State<DashboardPage> {

  final GlobalKey<ScaffoldState> scaffoldStateKey ;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldStateKey,
      body: Dashboard(scaffoldKey: scaffoldStateKey),
    );
  }

Your original Dashboard altered :

  class Dashboard extends StatefulWidget{

  Dashboard({Key key, this.scaffoldKey}):
    super(key: key);

  final GlobalKey<ScaffoldState> scaffoldKey ;

  @override
  _DashboardState createState() => new _DashboardState();
 }

Your _DashboardState with changes outlined :

 class _DashboardState extends State<Dashboard> {
   int _bottomNavBarCurrentIndex = 0;
   dashboardViews.DashboardView dView = new dashboardViews.DashboardView();

   List<Widget> _listOffers = new List<Widget>();

   Widget _currentView;

   void loadDashboardView() {
     _currentView = (_bottomNavBarCurrentIndex == 0
    ? dView.getOfferView(_listOffers, _getOfferData)
    : dView.getOrdersView());
   }

   _showInfoSheet() {
     showBottomSheet(
        context: widget.scaffoldKey.currentContext, // referencing the key passed from [DashboardPage] to use its Scaffold.
        builder: (context) {
          return Text('Hello');
        });
   }

   Future _getOfferData() async {
     loadDashboardView();

     List<Widget> _resultsOffers = new List<Widget>();

     SharedPreferences prefs = await SharedPreferences.getInstance();
     String _token = prefs.getString('token');

     final responseOffers =
     await http.get(globals.apiConnString + 'GetActiveOffers?token=$_token');

     if (responseOffers.statusCode == 200) {
       List data = json.decode(responseOffers.body);

       for (var i = 0; i < data.length; i++) {
         _resultsOffers.add(GestureDetector(
             onTap: () => _showInfoSheet(),
             child: Card(
                child: Padding(
                    padding: EdgeInsets.all(15),
                    child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                        Row(children: <Widget>[
                        Expanded(
                            flex: 5,
                            child: Text('${data[i]['Title']}',
                                style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                    color: globals.themeColor4))),
                        Expanded(
                            flex: 3,
                            child: Row(children: <Widget>[
                              Icon(Icons.access_time,
                                  size: 15, color: Colors.grey),
                              Padding(
                                  padding: EdgeInsets.fromLTRB(5, 0, 10, 0),
                                  child: Text('11:30 PM',
                                      style:
                                      TextStyle(color: Colors.black))),
                            ])),
                        Expanded(
                            flex: 1,
                            child: Row(children: <Widget>[
                              Icon(Icons.local_dining,
                                  size: 15, color: Colors.grey),
                              Padding(
                                  padding: EdgeInsets.fromLTRB(5, 0, 0, 0),
                                  child: Text('${i.toString()}',
                                      style:
                                      TextStyle(color: Colors.black))),
                            ])),
                      ]),
                      Padding(padding: EdgeInsets.all(10)),
                      Row(children: <Widget>[
                        Text(
                          'Created May 2, 2019 at 2:31 PM',
                          style: TextStyle(color: Colors.grey[600]),
                          textAlign: TextAlign.start,
                        )
                      ])
                    ])))));
      }
    }

    setState(() {
      _listOffers = _resultsOffers;
    });

    loadDashboardView();
  }


   void _bottomNavBarTap(int index) {
     setState(() {
      _bottomNavBarCurrentIndex = index;
      loadDashboardView();
    });
  }

   void pullRefresh() {
     _getOfferData();
   }

   @override
   Widget build(BuildContext context) {
     // Scaffold key has been removed as there is no further need to it.
     return Scaffold(
      backgroundColor: Colors.grey[200],
      body: _currentView,
      bottomNavigationBar: BottomNavigationBar(
         onTap: _bottomNavBarTap,
         currentIndex: _bottomNavBarCurrentIndex,
         items: [
           BottomNavigationBarItem(
               icon: Icon(Icons.near_me), title: Text('OFFERS')),
           BottomNavigationBarItem(
               icon: Icon(Icons.broken_image), title: Text('ORDERS'))
           ],
         ),
       );
     }
   }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM