Flutter:如何从 appbar 动作中显示快餐栏
Posted
技术标签:
【中文标题】Flutter:如何从 appbar 动作中显示快餐栏【英文标题】:Flutter: How to display a snackbar from an appbar action 【发布时间】:2019-04-30 19:21:58 【问题描述】:在执行来自AppBar
的操作后,我试图显示SnackBar
。
AppBar
无法从构建器构建,因此它无法访问 Scaffold 祖先。
我知道我们可以随时使用GlobalKey
对象来访问上下文,但我想知道是否有不使用GlobalKey
的解决方案。
我发现了一些 github 问题和 pull-request,但我无法从他们那里找到解决方案
=> https://github.com/flutter/flutter/issues/4581 和 https://github.com/flutter/flutter/pull/9380
更多上下文:
我有一个Appbar
和一个PopupMenuButton
,它们有一个项目。当用户单击此项目时,我会显示一个对话框,其中 showDialog
方法,如果用户单击“确定”,我想显示一个 SnackBar
【问题讨论】:
【参考方案1】:您可以使用 Builder 小部件
例子:
Scaffold(
appBar: AppBar(
actions: <Widget>[
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);
,
);
,
),
],
)
);
【讨论】:
这就是我要找的东西【参考方案2】:Scaffold.appBar
参数需要一个PreferredSizeWidget
,所以你可以有一个Builder
像这样:
appBar: PreferredSize(
preferredSize: Size.fromHeight(56),
child: Builder(
builder: (context) => AppBar(...),
),
),
【讨论】:
我尝试了您的解决方案,但是当我将上下文传递给构建警报的方法时,然后当我尝试显示 SnackBar 时,在此上下文中,我仍然有Scaffold.of() called with a context that does not contain a Scaffold
错误。
这个解决方案对我有用。我的电话:操作:builder: (context) => AppBar(...),
:确保您将 AppBar 代码写在括号内。如果您将 AppBar 提取到变量或方法中,它将停止工作。【参考方案3】:
一个选项是在对话框中使用两个上下文,并使用传递给对话框的上下文来搜索Scaffold
。
当你显示一个对话框时,你显示的是一个完全不同的页面/路由,它超出了调用页面的范围。所以没有脚手架。
下面是一个使用第一页范围的工作示例。
但是,问题在于 SnackBar
没有被删除。
如果您改为使用GlobalKey
来获取Scaffold
,问题是一样的。
在这种情况下,我会考虑不使用 Snackbar,因为它与下面的页面相关联。它甚至被对话框阴影变灰。
import 'package:flutter/material.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget
@override
Widget build(BuildContext context)
return new MaterialApp(
home: new MyHomePage(),
);
class MyHomePage extends StatelessWidget
_showDialog(BuildContext context1)
return showDialog(
context: context1,
builder: (BuildContext context)
return AlertDialog(
content: Text("Dialog"),
actions: <Widget>[
new FlatButton(
child: new Text("OK"),
onPressed: () => Scaffold.of(context1).showSnackBar(SnackBar(
content: Text("Pressed"),
)),
),
],
);
);
@override
Widget build(BuildContext context)
return new Scaffold(
appBar: new AppBar(
title: new Text("Test"),
actions: <Widget>[
PopupMenuButton(
itemBuilder: (BuildContext context)
return <PopupMenuEntry>[
PopupMenuItem(
child: ListTile(
title: Text('Show dialog'),
onTap: () => _showDialog(context),
),
),
];
,
)
],
),
);
【讨论】:
我为我的问题添加了更多上下文。我没有测试您的解决方案,但我想在来自PopupMenuButton
项目的对话后显示 SnackBar
我已根据您提供的附加信息更改了答案。
我测试过了。由于一些奇怪的行为,我找不到将它与我的代码集成的方法,但它正在工作。但是有几个问题:SnackBar 没有消失,动作菜单也没有自行消失。以上是关于Flutter:如何从 appbar 动作中显示快餐栏的主要内容,如果未能解决你的问题,请参考以下文章
如何在仍然显示Widgets的情况下将我的AppBar放在Flutter中的单独文件中?