首页 文章

如何实现Scafold.of()包装的“有效方式”

提问于
浏览
0

显示一个小吃栏作为动作的输出需要为Scafold.of()创建一个子上下文,如Scaffold的of method手册中所述 .

但我找不到这里描述的更“有效方法”的例子 .

更有效的解决方案是将构建函数拆分为多个小部件 . 这引入了一个新的上下文,您可以从中获取Scaffold . 在此解决方案中,您将拥有一个外部窗口小部件,用于创建由新内部窗口小部件的实例填充的脚手架,然后在这些内部窗口小部件中,您将使用Scaffold.of .

我想使用这种方法,因为所有递归缩进都是尽可能难以阅读的 . 我已经尝试使用函数创建我的表单的提交按钮,甚至尝试扩展RaisedButton类(因此 Scaffold.of 将在文档中指出的新实例化Widget中调用)无济于事 .

它只有在我的应用程序的主 Scaffold 中使用另一个 Builder 时才有效 .

这有效

class MyForm extends StatefulWidget {
  Login({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyFormState extends State<MyForm> {
  @override
  Widget build(BuildContext context) {
    final GlobalKey<FormState> _formKey = new GlobalKey<FormState>();
    return new Scaffold(
      body: new Builder(
        builder: (BuildContext context) {
          return new ListView(
            children: <Widget>[
              myForm(context, _formKey),
            ],
          );
        },
      ),
    );
  }
}

class SubmitButton extends RaisedButton {
  SubmitButton({
    Key key,
    this.onPressed,
    this.child,
  }) : super(key: key, onPressed: onPressed, child: child);
  final VoidCallback onPressed;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    return super.build(context);
  }
}

Widget myForm(
  BuildContext context,
  GlobalKey<FormState> _formKey) => new Container(
  child: new Form(
    key: _formKey,
    child: new Column(
      children: <Widget>[
        new TextFormField(
          validator: (value) {
            if (value.isEmpty) {
              return 'Write Something';
            }
          },
        ),
        new SubmitButton(
          onPressed: () {
            if (_formKey.currentState.validate()) {
              Scaffold.of(context).showSnackBar(
                  new SnackBar(content: new Text('Processing'))
              );
            }
          },
          child: new Text('Submit'),
        ),
      ],
    ),
  ),
);

如何删除 Builder 并简化它?我还试图进一步扩展 RaisedButton build() 方法,但进入了依赖/打字混乱 . 我找不到这方面的例子 .

2 回答

  • 2

    split your build function into several widgets 的一个简单方法就是在一个Widget的构建函数中创建Scaffold,在另一个Widget的构建函数中创建按钮 . (顺便说一句,代码中的 myForm 函数没有任何效果,因为它是作为同一构建函数的一部分运行的,因此上下文的值是相同的 . )我重构了你的代码以引入构建脚手架的MyPage Widget,并离开其余的在MyForm Widget中 . 但是,我们现在有两种不同的构建方法:一种构建Scaffold,另一种构建需要访问脚手架的窗体和按钮 .

    class MyPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          body: new MyForm(),
        );
      }
    }
    
    class MyForm extends StatefulWidget {
      @override
      _MyFormState createState() => new _MyFormState();
    }
    
    class _MyFormState extends State<MyForm> {
      final _formKey = new GlobalKey<FormState>();
    
      @override
      Widget build(BuildContext context) {
        return new ListView(
          children: <Widget>[
            new Container(
              child: new Form(
                key: _formKey,
                child: new Column(
                  children: <Widget>[
                    new TextFormField(
                      validator: (value) =>
                          (value.isEmpty) ? 'write something' : null,
                    ),
                    new RaisedButton(
                      onPressed: () {
                        if (_formKey.currentState.validate()) {
                          Scaffold.of(context).showSnackBar(new SnackBar(
                                content: new Text('Processing'),
                              ));
                        }
                      },
                      child: new Text('Submit'),
                    ),
                  ],
                ),
              ),
            ),
          ],
        );
      }
    }
    
  • 1

    是的,如果我们返回一个脚手架,那么这种背景无助于获得一个零食吧 . 通过使用GlobalKey,我们可以实现这一目标 . 请参阅下面的代码 .

    class ExampleWidget extends StatefulWidget {
      @override
      _ExampleWidgetState createState() => new _ExampleWidgetState();
    }
    
    class _ExampleWidgetState extends State<ExampleWidget> {
      GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState();
    
      _showSnackBar() {
        _scaffoldKey.currentState.showSnackBar(
        new SnackBar(
          content: new Text('You have clicked the button'),
          duration: new Duration(seconds: 4),
        ),
       );
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          key: _scaffoldKey,
          body: new Center(
            child: new RaisedButton(
              onPressed: _showSnackBar(),
              child: new Text('Click Me!'),
            ),
          ),
        );
      }
    }
    

相关问题