如何解决屏幕 initState 上的 Flutter Snackbar
三个问题:
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
void initState() {
print('In Init State Stream Builder');
_showSnackbar(context);
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text("Hello World"),),);
}
void _showSnackbar(BuildContext ctx) {
Scaffold.of(ctx).showSnackBar(
SnackBar(
content: ListTile(
onTap: () {
Scaffold.of(ctx).hideCurrentSnackBar();
},subtitle: Text("and i'm a subtitle"),trailing: Icon(Icons.check),duration: Duration(
days: 1,shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),behavior: SnackBarBehavior.floating,);
}
}
解决方法
我将在这里回答第一个问题。这里有两个问题。
-
在 Flutter 中,您不能在构建方法中包含 Scaffold 的小部件中调用
Scaffold.of(context)
。Scaffold.of(context)
必须始终从以Scaffold
作为其祖先的上下文中调用。 -
如果你想在 initState 中调用
showSnackbar
,你必须在一个延迟函数中调用它。持续时间可以为 0。
我这里有一个简单的例子来展示一个
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: ChildWidget(),);
}
}
class ChildWidget extends StatefulWidget {
@override
_ChildWidgetState createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildWidget> {
@override
Widget build(BuildContext context) {
return Container();
}
@override
void initState() {
Future<Null>.delayed(Duration.zero,() {
_showSnackbar();
});
super.initState();
}
void _showSnackbar() {
Scaffold.of(context).showSnackBar(SnackBar(content: Text('content')));
}
}
,
要在 initState() 上初始化 Snackbar,您可以设置延迟,也可以在构建布局后执行函数,如下所示:
void initState() {
super.initState();
WidgetsBinding.instance
.addPostFrameCallback((_) => _scaffoldKey.currentState.showSnackBar(SnackBar(content: Text("Your message here..")));
}
,
在 Flutter 中,context
仅在构建完成后可用,您可以使用 Future
或 WidgetsBinding.instance.addPostFrameCallback
或 SchedulerBinding.instance.addPostFrameCallback
。
但我希望如果您像这样将 _showSnackbar(context);
方法移动到 build
方法,您会得到相同的结果。
@override
Widget build(BuildContext context) {
_showSnackbar(context);
return Scaffold(
body: Center(
child: Text("Hello World"),),);
}
,
与其将它放在 initState() 中,不如将它放在 didChangeDependencies() 中
@override
void didChangeDependencies () {
print('In Init State Stream Builder');
_showSnackbar(context);
super.didChangeDependencies();
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。