如何实施"高效的方式" Scafold.of()包装

时间:2018-05-22 23:59:07

标签: flutter scaffold

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

但我无法找到这种更有效的方法的例子"这里描述。

  

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

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

仅当我在我的应用的主Builder内使用其他Scaffold时才有效。

这有效

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()方法,但遇到了依赖/打字混乱。我无法找到这方面的例子。

3 个答案:

答案 0 :(得分:2)

是的,如果我们返回一个脚手架,那么这个背景无助于获得一个零食吧。通过使用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!'),
        ),
      ),
    );
  }
}

答案 1 :(得分:1)

split your build function into several widgets的一个简单方法就是在一个Widget的构建函数中创建Scaffold,在另一个Widget的构建函数中创建按钮。 (顺便提一下,代码中的myForm函数没有任何效果,因为它是作为同一构建函数的一部分运行的,所以context的值是相同的。)我重构了你的代码以引入一个构建它的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'),
                ),
              ],
            ),
          ),
        ),
      ],
    );
  }
}

答案 2 :(得分:0)

  

如何删除并简化生成器?

现在。使用builder是最简单的方法。使用键是更复杂的方法(至少,它会添加更多行代码。

您需要做的就是仅添加一个构建器层

之前

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: ...,
  );
}

之后

@override
Widget build(BuildContext context) {
  return Scaffold(
    body: Builder(
      builder: (c) => ...,
    ),
  );
}

还有什么更简单的?