Flutter: 如何在应用栏操作中显示一个 snackbar
Flutter: 如何在应用栏操作中显示一个 snackbar
我正在尝试在从AppBar执行一个操作后显示一个SnackBar。AppBar无法通过构建器进行构建,因此无法访问其Scaffold祖先。我知道我们可以使用GlobalKey对象在需要时访问上下文,但我想知道是否有一种不使用GlobalKey的解决方案。我在一些GitHub问题和拉取请求中找到了一些解决方案,但是我找不到一个解决方案。
=> https://github.com/flutter/flutter/issues/4581 和 https://github.com/flutter/flutter/pull/9380
一些更多的背景信息:
我有一个带有PopupMenuButton的Appbar,其中有一个项目。当用户点击此项目时,我使用showDialog方法显示一个对话框,如果用户点击“确定”,我想显示一个SnackBar。
问题的原因是在构建AppBar时,将context传递给显示Snackbar的方法后,使用该context显示Snackbar时出现错误。解决方法是将AppBar的构建代码直接写在Builder的builder函数内部,而不是将其提取为变量或方法。以下是解决方法的完整代码:
appBar: PreferredSize(
preferredSize: Size.fromHeight(56),
child: Builder(
builder: (context) => AppBar(
actions:
IconButton(
icon: const Icon(Icons.settings),
onPressed: () => _handleSettings(Scaffold.of(context)),
),
],
),
),
),
此解决方法已经经过验证,可以正常工作。
问题出现的原因是当显示对话框时,实际上是显示了一个完全不同的页面/路由,它不在调用页面的范围内,因此无法获取到 Scaffold。解决方法是使用两个上下文,在对话框中使用传递给对话框的上下文来搜索 Scaffold。
下面是一个使用第一个页面范围的工作示例。
问题是 SnackBar 没有被移除。如果使用 GlobalKey 来获取 Scaffold,问题仍然存在。
考虑在这种情况下不使用 Snackbar,因为它与下面的页面相关联,甚至被对话框阴影变暗。
根据提供的额外信息,我对答案进行了修改。
我已经测试过了。由于一些奇怪的行为,我找不到将其与我的代码集成的方法,但它是有效的。但是有几个问题:SnackBar 不会消失,操作菜单也不会自动消失。
问题出现的原因是在AppBar的操作按钮中无法直接显示Snackbar,需要使用Builder widget来建立一个新的BuildContext,以便能够访问Scaffold的上下文。
解决方法是在AppBar的actions中添加一个Builder widget,并在其builder函数中返回一个IconButton。然后,在IconButton的onPressed回调中,创建一个SnackBar,并使用Scaffold的上下文调用showSnackBar方法来显示Snackbar。
具体代码示例如下:
Scaffold(
appBar: AppBar(
actions:
Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(Icons.message),
onPressed: () {
final snackBar = SnackBar(content: Text('Yay! A SnackBar!'));
Scaffold.of(context).showSnackBar(snackBar);
},
);
},
),
],
)
);
通过以上方法,我们可以在AppBar的操作按钮中显示一个Snackbar。