正如你所看到的,我的按钮在Scaffold的身体里。但是我得到了这个例外:
使用不包含Scaffold的上下文调用Scaffold.of()。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('SnackBar Playground'),
),
body: Center(
child: RaisedButton(
color: Colors.pink,
textColor: Colors.white,
onPressed: _displaySnackBar(context),
child: Text('Display SnackBar'),
),
),
);
}
}
_displaySnackBar(BuildContext context) {
final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
Scaffold.of(context).showSnackBar(snackBar);
}编辑:
我找到了另一个解决这个问题的方法。如果我们给Scaffold一个键,即GlobalKey<ScaffoldState>,我们可以按下面的方式显示SnackBar,而不需要将我们的身体封装在Builder小部件中。不过,返回Scaffold的小部件应该是一个状态小部件。
_scaffoldKey.currentState.showSnackBar(snackbar); 发布于 2018-07-12 11:40:25
之所以会出现此异常,是因为您使用的是实例化context的小部件的Scaffold。不是context的一个孩子的Scaffold。
您可以通过使用不同的上下文来解决这个问题:
Scaffold(
appBar: AppBar(
title: Text('SnackBar Playground'),
),
body: Builder(
builder: (context) =>
Center(
child: RaisedButton(
color: Colors.pink,
textColor: Colors.white,
onPressed: () => _displaySnackBar(context),
child: Text('Display SnackBar'),
),
),
),
);注意,虽然我们在这里使用Builder,但这并不是获得不同BuildContext的唯一方法。
还可以将子树提取到不同的Widget中(通常使用extract widget重构)。
发布于 2018-12-21 18:04:47
您可以使用GlobalKey。唯一的缺点是使用GlobalKey可能不是最有效的方法。
这方面的一个好处是,您还可以将此键传递给其他不包含任何脚手架的定制小部件类。见(这里)
class HomePage extends StatelessWidget {
final _scaffoldKey = GlobalKey<ScaffoldState>(); \\ new line
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey, \\ new line
appBar: AppBar(
title: Text('SnackBar Playground'),
),
body: Center(
child: RaisedButton(
color: Colors.pink,
textColor: Colors.white,
onPressed: _displaySnackBar(context),
child: Text('Display SnackBar'),
),
),
);
}
_displaySnackBar(BuildContext context) {
final snackBar = SnackBar(content: Text('Are you talkin\' to me?'));
_scaffoldKey.currentState.showSnackBar(snackBar); \\ edited line
}
}发布于 2019-05-01 10:57:00
更新- 2021
Scaffold.of(context)被反对为ScaffoldMessenger。
请从方法的文档中检查这一点:
ScaffoldMessenger现在处理SnackBars,以便在各路由之间持久化,并且始终显示在当前Scaffold上。默认情况下,根ScaffoldMessenger包含在MaterialApp,中,但您可以为ScaffoldMessenger创建自己的受控范围,以进一步控制哪些脚手架接收SnackBars。
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo')
),
body: Builder(
// Create an inner BuildContext so that the onPressed methods
// can refer to the Scaffold with Scaffold.of().
builder: (BuildContext context) {
return Center(
child: RaisedButton(
child: Text('SHOW A SNACKBAR'),
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: Text('Hello!'),
));
},
),
);
},
),
);
}您可以检查详细的弃用和新方法这里。
https://stackoverflow.com/questions/51304568
复制相似问题