屏幕 initState 上的 Flutter Snackbar
Flutter Snackbar on screen initState
三个问题:
- 如何在 flutter 中的 initState 或应用程序加载初始屏幕时加载 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();
}
这对我有用:)
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((_) {
// do what you want here
final snackBar = SnackBar(
content: const Text('Yay! A SnackBar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Some code to undo the change.
},
),
);
// Find the ScaffoldMessenger in the widget tree
// and use it to show a SnackBar.
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}
三个问题:
- 如何在 flutter 中的 initState 或应用程序加载初始屏幕时加载 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();
}
这对我有用:)
@override
void initState() {
super.initState();
WidgetsBinding.instance!.addPostFrameCallback((_) {
// do what you want here
final snackBar = SnackBar(
content: const Text('Yay! A SnackBar!'),
action: SnackBarAction(
label: 'Undo',
onPressed: () {
// Some code to undo the change.
},
),
);
// Find the ScaffoldMessenger in the widget tree
// and use it to show a SnackBar.
ScaffoldMessenger.of(context).showSnackBar(snackBar);
});
}