【问题标题】:showBottomSheet Scaffold issue with contextshowBottomSheet 脚手架问题与上下文
【发布时间】:2019-10-06 18:27:49
【问题描述】:

尝试在我的应用中实现 showBottomSheet,但它抛出错误:Scaffold.of() 调用的上下文不包含 Scaffold。

在网上搜索了一下之后,我添加了一个 GlobalKey,但这似乎没有起到作用。有人有什么建议吗?

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'))
        ],
      ),
    );
  }
}

希望有人能指出正确的方向,谢谢!

编辑:这是我查看的具有相同问题的链接之一,我尝试按照建议将构建器上下文设置为 c 但没有奏效:https://github.com/flutter/flutter/issues/23234

编辑 2:当我使用不包含 Scaffold 错误的上下文调用 Scaffold.of() 时,添加显示变量内容的屏幕截图。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您收到此错误的原因是您在其构建过程中调用了Scaffold,因此您的showBottomSheet 函数看不到它。解决此问题的方法是为有状态小部件提供Scaffold,为Scaffold 分配一个键,然后将其传递给您的Dashboard(我假设它是您的状态类中的有状态小部件的名称)。您无需为_DashboardStatebuild 内的Scaffold 分配密钥。

    这是您提供Scaffoldkey 的类:

     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),
        );
      }
    

    您原来的Dashboard 已更改:

      class Dashboard extends StatefulWidget{
    
      Dashboard({Key key, this.scaffoldKey}):
        super(key: key);
    
      final GlobalKey<ScaffoldState> scaffoldKey ;
    
      @override
      _DashboardState createState() => new _DashboardState();
     }
    

    您的_DashboardState 概述了更改:

     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'))
               ],
             ),
           );
         }
       }
     }
    

    【讨论】:

    • 感谢您的回复!我尝试了您的更改,但现在我收到另一个错误:NoSuchMethodError: The getter 'currentContext' was called on null, 这是由:widget.scaffoldKey.currentContext
    • 我是个白痴。如果用户已登录,我有一些代码绕过 Dashboard()。我现在添加了包装器,它更好。但是,我仍然收到一个错误:使用不包含 Scaffold 的上下文调用 Scaffold.of()。我正在添加一个屏幕截图,显示我正在传递的上下文,正如你所建议的,确实似乎有一个脚手架。
    • 哈哈!不要对自己太苛刻,错误会发生。
    猜你喜欢
    • 2020-11-09
    • 2010-10-23
    • 2020-05-28
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    相关资源
    最近更新 更多