ScaffoldMessenger.of(context).showSnackBar() 在小部件构建函数中直接调用时不起作用
Posted
技术标签:
【中文标题】ScaffoldMessenger.of(context).showSnackBar() 在小部件构建函数中直接调用时不起作用【英文标题】:ScaffoldMessenger.of(context).showSnackBar() doesn't work when called directly inside a widget build function 【发布时间】:2021-10-03 03:02:18 【问题描述】:在寻找使用颤振SnackBar
和ScaffoldMessenger
的示例时,我只找到了onPressed
函数的用法:
Widget build(BuildContext context)
return Container(
child: ElevatedButton(
child: ...,
onPressed: () => _showToast(context),
));
void _showToast(BuildContext context)
final scaffold = ScaffoldMessenger.of(context);
scaffold.showSnackBar(
SnackBar(content: const Text('Added to favorite')),
);
但没有一个示例解释了为什么必须仅将它与 onPressed 一起使用, 所以我自己尝试并直接在构建函数中使用:
Widget build(BuildContext context)
_showToast(context); <---
return Container(
child: ElevatedButton(
...,
));
但是我得到了这个错误:
我不知道为什么会这样。
我最终给了 Scaffold 一个密钥并使用了 GlobalKey<ScaffoldState>
方法,但我真的很想了解为什么在没有回调的情况下使用 ScaffoldMessenger.of(context).showSnackBar()
\onPressed 不起作用
【问题讨论】:
【参考方案1】:虽然ScaffoldMessenger.of(context)
我们需要一些时间来正确渲染(对于完整的 Scaffold)。我们可以从addPostFrameCallback
知道时间。此外,如果您尝试显示小部件的中间部分,第一部分将呈现,但其余小部件将面临此问题。
这里是build
方法的解决方案。
WidgetsBinding.instance!.addPostFrameCallback((timeStamp)
_showToast(context);
);
要正确理解这个概念,我们可以这样做。
Scaffold(
body: Container(
height: 100,
color: Colors.cyanAccent,
child: Column(
children: [
Text("This text will render "),
Builder(builder: (context)
_showToast(context);
///but you will be able to see Message
return Text("it will cause error");
),
Text("This text will not render "),
],
),
),
);
【讨论】:
我接受了这个答案,因为它解释了完整的脚手架渲染概念并给出了这个概念的示例。【参考方案2】:尝试在 Future.deleayd
中添加或声明您的小吃吧Future.delayed(Duration.zero, () async
yourSnackBarFunction();
);
【讨论】:
我的目标是了解我收到错误的原因。虽然我认为你的解决方案会奏效...... 我不推荐它,它以某种方式“欺骗”了框架,通常不可取。 我用 GlobalKey 解决了这个问题(正如我在帖子中提到的),但我真的很想了解它为什么会发生 将“构建”方法视为 Flutter 引擎的秘诀,如果发生任何需要重建的情况,如何组装您的小部件。见api.flutter.dev/flutter/material/ScaffoldState/build.html。 @vigdora 我认为 future.deleyed 在延迟后运行它的计算。 [computation] 将在给定的 [duration] 过去后执行,future 以计算结果完成。【参考方案3】:在 Flutter 中,每当需要重建小部件时,框架本身都会调用 build 函数。它可以发生多次!
另一方面,当您想通知用户某事时,您通常希望显示一个 toast/snackbar。所以你可以在 onPressed 和许多其他地方显示一个snackbar,但是构建函数本身只是用于构建一个小部件,而不是直接响应用户操作。
【讨论】:
谢谢,但是当颤振绑定你使用scaffoldMessenger的上下文时,它限制你只能在无状态小部件的构建方法中使用它......我可能想在构建函数之外使用toast .. 我可能错了,但我认为您也可以从其他地方访问上下文,而不仅仅是构建方法。例如,如果您在“class _SomeState extends State以上是关于ScaffoldMessenger.of(context).showSnackBar() 在小部件构建函数中直接调用时不起作用的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery:标准 SQL 和 PERCENTILE_CONT() 函数