我无法理解以下代码片段中Widget BuildContext
和Builder BuildContext
之间的差异:
@override
Widget build(BuildContext context) {
和
new Builder(
builder: (BuildContext context){
通过使用Widget BuildContext
,SnackBar 不会出现在 UI 中,但日志中会显示一个错误,表明Scaffold.of() Context
在使用Builder context
时没有脚手架,一切正常。
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text('Processing Data')));
编辑:主.dart文件:
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'APP'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final formKey = new GlobalKey<FormState>();
String username;
@override
//This context
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
body: new Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new Flexible(
child: new Container(
child: new Center(
child: new Text(widget.title),
),
),
flex: 1,
),
new Form(
key: formKey,
child:
new Row(children: <Widget>[
new Flexible(child:
new Container(
margin: EdgeInsets.zero,
child: new TextFormField(
decoration:
new InputDecoration(
hintText: 'Username',
labelText: "1",
labelStyle: new TextStyle(color: new Color.fromARGB(255, 0, 0, 0)),
),
validator: (val) => val.isEmpty? 'Username can't be empty.' : null,
),
),
flex: 1,
),
new Flexible(child:
new Container(
margin: EdgeInsets.only(
left: 8.0,
right: 8.0,
),
child: new TextFormField(
decoration: new InputDecoration(
border: InputBorder.none,
hintText: "Password",
),
validator: (val) => val.isEmpty? 'Password can't be empty.' : null,
obscureText: true,
),
),
flex: 1,
),
new Container(
child:
new Builder(
//And this context
builder: (BuildContext context){
return RaisedButton(
child: new Text("Sign in"),
onPressed: (){
if (formKey.currentState.validate()) {
// If the form is valid, display a snackbar. In the real world, you'd
// often want to call a server or save the information in a database
Scaffold.of(context).showSnackBar(
new SnackBar(content: new Text('Processing Data')));
}
},
);
},
),
),
],
),
),
],
),
),
);
}
}
最好使用它们key
属性引用当前Scaffold
,希望SnackBar
出现在其中。
final GloabalKey<ScaffoldState> _key = GlobalKey<ScaffoldState>();
Scaffold(
key:_key,
...
)
展示小吃店
_key.currentState.showSnackBar(mySnackBar)
请注意,每个构建器方法都会获得一个context
,以便在使用需要访问此上下文的小部件时能够引用它。在您的代码中,context
被混淆了,如果您将build
方法更改为context
像(Buildcontext scaffoldContext)
这样独特的方法,然后使用Scaffold.of(scaffoldContext)
我不确定这是否有效,因为我经常在 Flutter 中看到这种混淆。
无论如何,上面的解决方案更干净。