代码之家  ›  专栏  ›  技术社区  ›  Figen Güngör

使用不包含scaffold的上下文调用scaffold.of()

  •  57
  • Figen Güngör  · 技术社区  · 7 年前

    你可以看到我的扣子在脚手架的里面。但我有个例外:

    使用不包含scaffold的上下文调用scaffold.of()。

    import 'package:flutter/material.dart';
    
    void main() => runApp(MyApp());
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: HomePage(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('SnackBar Playground'),
          ),
          body: Center(
            child: RaisedButton(
              color: Colors.pink,
              textColor: Colors.white,
              onPressed: _displaySnackBar(context),
              child: Text('Display SnackBar'),
            ),
          ),
        );
      }
    }
    
    _displaySnackBar(BuildContext context) {
      final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
      Scaffold.of(context).showSnackBar(snackBar);
    }
    

    编辑:

    我找到了解决这个问题的另一个办法。如果我们给scaffold一个键globalkey,我们可以如下显示snackbar,而不需要用builder小部件包装我们的身体。返回scaffold的小部件应该是有状态的小部件。

     _scaffoldKey.currentState.showSnackBar(snackbar); 
    
    3 回复  |  直到 7 年前
        1
  •  119
  •   Rémi Rousselet    7 年前

    发生此异常是因为您正在使用 context 实例化的小部件的 Scaffold 是的。不是那个 上下文 一个孩子的 脚手架 是的。

    只需使用不同的上下文即可解决此问题:

    Scaffold(
        appBar: AppBar(
            title: Text('SnackBar Playground'),
        ),
        body: Builder(
            builder: (context) => 
                Center(
                child: RaisedButton(
                color: Colors.pink,
                textColor: Colors.white,
                onPressed: () => _displaySnackBar(context),
                child: Text('Display SnackBar'),
                ),
            ),
        ),
    );
    

    注意,当我们使用 Builder 在这里,这不是唯一的方法来获得不同的 BuildContext 是的。

    也可以将子树提取为不同的 Widget (通常使用 extract widget 重构)

        2
  •  56
  •   Lebohang Mbele    7 年前

    你可以用 GlobalKey 是的。唯一的缺点是使用globalkey可能不是最有效的方法。

    这方面的一个好处是,您还可以将此密钥传递给其他不包含任何脚手架的自定义小部件类。见( here )

    class HomePage extends StatelessWidget {
      final _scaffoldKey = GlobalKey<ScaffoldState>(); \\ new line
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: _scaffoldKey,                           \\ new line
          appBar: AppBar(
            title: Text('SnackBar Playground'),
          ),
          body: Center(
            child: RaisedButton(
              color: Colors.pink,
              textColor: Colors.white,
              onPressed: _displaySnackBar(context),
              child: Text('Display SnackBar'),
            ),
          ),
        );
      }
    }
    
    _displaySnackBar(BuildContext context) {
      final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
      _scaffoldKey.currentState.showSnackBar(snackBar);   \\ edited line
    }
    
        3
  •  7
  •   SANAT    7 年前

    从方法文档中检查:

    当在同一个构建函数中实际创建脚手架时, 无法使用生成函数的上下文参数来查找 scaffold(因为它“高于”返回的小部件)。在这样的 在案例中,可以使用构建器的以下技术来提供 具有“在”脚手架下的BuildContext的新作用域:

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('Demo')
        ),
        body: Builder(
          // Create an inner BuildContext so that the onPressed methods
          // can refer to the Scaffold with Scaffold.of().
          builder: (BuildContext context) {
            return Center(
              child: RaisedButton(
                child: Text('SHOW A SNACKBAR'),
                onPressed: () {
                  Scaffold.of(context).showSnackBar(SnackBar(
                    content: Text('Hello!'),
                  ));
                },
              ),
            );
          },
        ),
      );
    }
    

    您可以从 of method 文件

        4
  •  5
  •   afcode    6 年前

    解决此问题的简单方法是使用以下代码为您的scaffold创建一个类似于final的键:

    第一: GlobalKey<ScaffoldState>() _scaffoldKey = GlobalKey<ScaffoldState> ();

    第二步:给你的脚手架分配钥匙 key: _scaffoldKey

    第三:使用 _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Welcome")));

        5
  •  2
  •   Sanjayrajsinh    6 年前

    解决这个问题有两种方法

    1)使用builder小部件

    Scaffold(
        appBar: AppBar(
            title: Text('My Profile'),
        ),
        body: Builder(
            builder: (ctx) => RaisedButton(
                textColor: Colors.red,
                child: Text('Submit'),
                onPressed: () =>  Scaffold.of(ctx).showSnackBar(SnackBar(content: Text('Profile Save'),
                ),
            ),
        ),
    );
    

    2)使用Globalkey

    class HomePage extends StatelessWidget {
      final globalKey = GlobalKey<ScaffoldState>(); 
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          key: globalKey,       
          appBar: AppBar(
            title: Text('My Profile'),
          ),
          body:  RaisedButton(
              textColor: Colors.red,
              child: Text('Submit'),
              onPressed: showSnackbar(context),
            ),
          ),
        );
      }
    }
    
    void showSnackbar(BuildContext context) {
      final snackBar = SnackBar(content: Text('Profile saved'));
      globalKey.currentState.showSnackBar(snackBar);  
    }