作者: Joe Birch
原文地址:https://flutterdoc.com/bottom-sheets-in-flutter-ec05c90453e7
Bottom sheets
(底部菜单或底部页面)是(移动设备)屏幕底部展示内容给用户的视图(widget) — 这样或许可以促进与用户进一步的交互或展示其他内容的一些形式。通常固定在屏幕的底部,并方便用户隐藏。在Flutter中,有2种开箱即用(声明式)的bottom sheet widget
,分别是 Persistent Bottom Sheet 和 Modal Bottom Sheet — 那么我们来看下这些widget是如何运行,同时在我们的apps中如何去使用它们。
如果你对Bottom Sheets
还不了解的话,我们可以从material design
规范中拿一个例子来说明下:
在图的左边是一个persisten botttom sheet
,在这个案例中,它可以上下滑动来弹出并展示当前播放的歌曲 — 在视图外保持持久状态。在图右边,我们有一个modal bottom sheet
,通常用于对屏幕显示内容进行交互。
Modal Bottom Sheet(模态底部菜单)
当一个modal bottom sheet
展示时,它可以看做是一个阻止窗口组件 — 这意味着阻止用户在应用当前页面的其他地方进行操作。这可以视为向用户展示某种形式的菜单或对话框的替代方案。点击back
或是点击除了底部菜单以外的地方会从视图中将它消除。
我们可以通过showModalBottomSheet
方法来创建一个底部菜单,完成此操作后,再使用Navigator将菜单作为路由推到应用的navigator中。
1 | showModalBottomSheet<void>(context: context, |
在我们的应用中运行以上的代码,然后我们会发现在屏幕的底部会出现底部菜单。
关于showModalBottomSheet
中的builder
参数,我们只需返回要在bottom sheet
中显示的widget
。这根据你的需求而定,但是在本例中我使用了Column
来展示一些ListTile
实例的集合,来呈现出以上的符合material
指南中的视图。当点击bottom sheet
之外的地方时,对话框将被撤销并在视图中完全删除。因为这是一个modalbottom sheet
,没有持久状态的存在。它可以在当前上下文中调用某种形式的操作。
注意:如果使用Column
来展示表单的内容,则必须使用mainAxisSize
中的MainAxisSize.min
来确保包装内容。
Persistent Bottom Sheet(持久底板)
当展示一个持久的底部菜单时,通常用于显示应用当前页面所相符的内容 。这些sheet
经常被用于显示上下文来关联内容,同时将用户的路由
保持在当前。点击返回或者将菜单向下弹出都会使得sheet
向下弹出直到提示用户操作。然而,此时它处于准备以便于用户再次弹出。
当我们想要使用持久性底层时,我们需要做一些不同的事情。 首先,我们需要创建一个新的GlobalKey
实例,以便我们可以访问Scaffold
,它将用于显示我们的持久底页。
1 | final GlobalKey<ScaffoldState> _scaffoldKey = new |
然后在Scaffold
中这样设置:
1 | return new Scaffold( |
之后我们使用这个Scaffold
键值来获取当前状态并展示persistent bottom sheet
:
1 | _scaffoldKey.currentState |
我们需要这个额外的的设置,因为持久的底部表格在工作方式上与模态式会有一些不同。模态式的底部表单本质上是一个阻止对话框,所以它可以在屏幕上向用户展示。但是因为持久式的底部菜单需要滑入和滑出视图,对当前的上下文进行补充,所以需要知道当前显示它的Scaffold
。
当说到底部表单的内容时,就像模态式底部页,我们需要提供一个用于显示的组件。
这仅有的区别是,我们需要注意所展示的内容。正如在这篇文章最开始所展示materail design
例图那样,持久性底页始终对用户可见,即使它未被展开。因此,你可能想将一些标题内容在底页展开时保留在视图中,或者转换为其他形式的内容来提供用户进一步的操作。
另一方面,你应该看到了持久性的底页不会覆盖它的背景,因为不需要阻止用户其他操作。与模态式底页不同,它可以通过在窗口小部件上执行垂直滑动操作来上下弹出。
当我们调用showBottomSheet
函数时,会获得一个PersistentBottomSheetController
实例,我们可以使用这个控制器来关闭这个底页:
1 | PersistentBottomSheetController controller = |
我们也可以监听之后控制器传来的关闭事件,当底页关闭时,我们就可以做一些操作:
1 | controller.closed.then(...) |
我希望这篇文章能够进一步深入了解如何在应用程序中实现底页,以及哪一个是正确的。 如果您有任何问题或意见,请联系!