将一个小吃栏显示为动作的输出需要为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()
方法,但遇到了依赖/打字混乱。我无法找到这方面的例子。
答案 0 :(得分:2)
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) => ...,
),
);
}
还有什么更简单的?