android studio 3.6
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: new ThemeData(
primaryColor: new Color(Constants.COLOR_PRIMARY),
primaryTextTheme: TextTheme(headline6: TextStyle(color: Colors.white))),
home: new SignInForm());
}
}
class SignInForm extends StatefulWidget {
@override
State<StatefulWidget> createState() {
logger.d("createState:");
return new _SignInFormState();
}
}
class _SignInFormState extends State {
final _formKey = GlobalKey<FormState>();
final _scaffoldKey = GlobalKey<ScaffoldState>();
String _textVersion = "";
String _email = null;
String _password = null;
@override
Widget build(BuildContext context) {
logger.d("build:");
//String _errorMessage = null;
return Scaffold(
appBar: new AppBar(
centerTitle: true,
title: new Text('Sign in',
style: TextStyle(fontWeight: FontWeight.bold))),
body: new Container(
margin: const EdgeInsets.only(
left: Constants.DEFAULT_MARGIN,
right: Constants.DEFAULT_MARGIN),
child: new Form(
key: _formKey,
child: new Column(children: [
new TextFormField(
decoration: new InputDecoration(hintText: 'Email'),
keyboardType: TextInputType.emailAddress,
onChanged: (value) {
setState(() {
_email = value;
});
}),
new TextFormField(
decoration: new InputDecoration(hintText: 'Password'),
obscureText: true),
new Container(
margin: const EdgeInsets.only(
top: Constants.DEFAULT_MARGIN / 2),
height: Constants.MIN_HEIGHT,
child: new Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
new Text("Forgot password?",
style: TextStyle(
color: new Color(Constants.COLOR_PRIMARY))),
new Align(
alignment: Alignment.centerRight,
child: new RaisedButton(
// Buttons are disabled by default
child: Text('Sign in'.toUpperCase()),
color: new Color(Constants.COLOR_PRIMARY),
textColor: new Color(
Constants.COLOR_PRIMARY_TEXT_COLOR),
onPressed: () {
if (_formKey.currentState.validate()) {
logger.d(
"onPressed: check_email = $_email");
if (_email == null ||
_email.trim().isEmpty) {
logger.d(
"onPressed: show_error_message");
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text("Аll fields must be filled"),
backgroundColor: Colors.red));
}
}
}))
])),
new Container(
margin: const EdgeInsets.all(Constants.DEFAULT_MARGIN),
child: new Text('Registration'.toUpperCase(),
style: new TextStyle(
color: new Color(Constants.COLOR_PRIMARY),
fontWeight: FontWeight.bold))),
new Container(
margin: const EdgeInsets.all(Constants.DEFAULT_MARGIN),
child: new Text(_textVersion))
]))));
}
按下按钮并得到错误提示 在这一行:
Scaffold.of(context).showSnackBar(
logcat:
The context used was: SignInForm
state: _SignInFormState#fe66a
When the exception was thrown, this was the stack:
#0 Scaffold.of (package:flutter/src/material/scaffold.dart:1456:5)
#1 _SignInFormState.build.<anonymous closure> (package:flutter_sample/signinform.dart:86:52)
#2 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:779:14)
#3 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:862:36)
#4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:182:24)
...
Handler: "onTap"
Recognizer: TapGestureRecognizer#74eb7
debugOwner: GestureDetector
state: possible
won arena
finalPosition: Offset(268.7, 208.0)
finalLocalPosition: Offset(52.7, 18.0)
button: 1
sent tap down
答案 0 :(得分:1)
发生此问题是因为当前传递的上下文没有任何匹配的祖先(在本例中为匹配的祖先支架)。
解决此问题的最简单方法是在您的MyApp中,替换:
home: new SignInForm()
具有:
home: Scaffold(body: SignInForm())
您必须指定脚手架的关键属性:
Scaffold(key: _scaffoldKey, body: // Your remaining code);
并使用以下方法显示小吃店
:_scaffoldKey.currentState.showSnackBar(
SnackBar(content: Text("Аll fields must be filled"),
backgroundColor: Colors.red)
);
您可以使用Builder小部件来解决此问题:
Scaffold(body: Builder(builder: (context) {
return Container(child:// Your widget);
// No other change needed
},);
我个人更喜欢选项3。
在同一构建函数中实际创建了脚手架时, 构建函数的上下文参数不能用于查找 脚手架(因为它在“上方”,因此在小部件中返回了小部件 树)。