如何在EventChannel.listen的回调函数onEvent中显示SnackBar
如何在EventChannel.listen的回调函数onEvent中显示SnackBar
使用EventChannel
从原生代码接收事件。
内容是字符串,我想用SnackBar
来显示它。
但是Scaffold.of
返回null。我找不到任何方法来获取由Widget Build(...)
创建的Scaffold
的BuildContext
。
代码如下:
@override
void initState() {
super.initState();
showMsg.receiveBroadcastStream().listen(
(event) => setState(() {
Scaffold.of(context).showSnackBar(new SnackBar(
content: new Text(event.toString()),
));
}),
onError: (event) => {}
);
问题的原因是在onPressed回调中调用Scaffold.of(context).showSnackBar方法时出现错误,因为该方法需要在Scaffold的子组件中调用。
解决方法是将Scaffold的子组件封装成一个新的StatefulWidget,并在该组件中调用showSnackBar方法。
以下是修改后的代码:
import 'package:flutter/material.dart';
void main() => runApp(SnackBarExample());
class SnackBarExample extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'SnackBar Example',
home: Scaffold(
appBar: AppBar(
title: Text('SnackBar Example'),
),
body: SnackBarPage(),
),
);
}
}
class SnackBarPage extends StatefulWidget {
@override
_SnackBarPageState createState() => _SnackBarPageState();
}
class _SnackBarPageState extends State
@override
Widget build(BuildContext context) {
return Center(
child: RaisedButton(
onPressed: () {
final snackBar = SnackBar(
content: Text('This is a SnackBar!'),
action: SnackBarAction(
label: 'Action',
onPressed: () {
// Some code to action.
},
),
);
Scaffold.of(context).showSnackBar(snackBar);
},
child: Text('Showing SnackBar'),
),
);
}
}
这样,我们就将Scaffold的子组件封装成了一个新的StatefulWidget,并在该组件的State中调用showSnackBar方法,解决了在回调中显示SnackBar的问题。
问题的原因是在Flutter的更新版本中,使用ScaffoldMessenger
来显示SnackBar
,而不是使用Scaffold
的showSnackBar
方法。解决方法是使用以下代码来显示SnackBar
:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('test'),
),
);
在旧版本中,需要使用Scaffold
的key
来获取Scaffold
的状态,然后调用showSnackBar
方法来显示SnackBar
。具体做法是:
1. 创建一个GlobalKey<ScaffoldState>
类型的全局变量_scaffoldKey
。
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
2. 在build
方法中,将Scaffold
的key
属性赋值为_scaffoldKey
。
return new Scaffold(
key: _scaffoldKey,
...,
);
3. 使用_scaffoldKey.currentState.showSnackBar
来显示SnackBar
。
_scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text(event.toString()),
));
另外,需要注意的是,_scaffoldKey
不能放在一个StatelessWidget
中,而是应该放在一个State<>
类中,因为这是保存状态的最佳做法。