前面的小节把常用的一些部件都介绍了,这节介绍下 Flutter
中的一些操作提示。Flutter
中的操作提示主要有这么几种 SnackBar
、BottomSheet
、Dialog
,因为 Dialog
样式比较多,放最后讲好了
SnackBar
SnackBar
的源码相对简单
1 | const SnackBar({ |
例如我们需要实现一个功能,修改某个值,修改后给用户一个提示,同时给用户一个撤销该操作的按钮,那么就可以通过 SnackBar
来简单实现。还有就是 SnackBar
可以和 floatingActionButton
完美的配合,弹出的时候不会遮挡住 fab
1 | class _PromptDemoPageState extends State<PromptDemoPage> { |
可以看下最后的效果图,请注意看 fab
和值的变化:
BottomSheet
BottomSheet
看命名就知道是从底部弹出的菜单,展示 BottomSheet
有两种方式,分别是 showBottomSheet
和 showModalBottomSheet
,两种方式只有在展示类型上的差别,方法调用无差,而且 showBottomSheet
和 fab
有组合动画,showModalBottomSheet
则没有,看下实际的例子吧。在 ListView
中增加一个 BottomSheet
的按钮,因为 BottomSheet
需要的 context
也不能是 Scaffold
下的 context
,所以需要通过 Builder
进行包裹一层,然后增加 _showBottomSheet
的方法
1 | _showBottomSheet(BuildContext context) { |
把 showBottomSheet
替换成 showModalBottomSheet
就是另外一种展示方式了,内部不需要做任何改变,我们看下两种的运行效果:
可以看到 showBottomSheet
会充满整个屏幕,然后 fab
会跟随一起到 AppBar
的底部位置,而 showModalBottomSheet
展示的高度不会超过半个屏幕的高度,但是 fab
被其遮挡了。假如我们只需要展示 2-3 个 item
,但是按照刚才的方式 showModalBottomSheet
的高度太高了,那我们可以在 ListView
外层包裹一层 Container
,然后指定 height
即可
1 | _showModalBottomSheet(BuildContext context) { |
修改高度后的效果:
Dialog
相对于 SnackBar
和 BottomSheet
,Dialog
的使用场景相对会更多,在 MaterialDesign
下,Dialog
主要有 3 种:AlertDialog
,SimpleDialog
和 AboutDialog
,当然在 Cupertino
风格下也有相应的 Dialog
,因为这个系列以 MaterialDesign
风格为主,所以 Cupertiono
等下次有时间再写吧。
AlertDialog
在 ListView
中增加一个 AlertDialog
的按钮,用于点击显示 AlertDialog
用,然后加入显示 AlertDilaog
的方法,并将按钮的 onPressed
指向该方法,Dialog
的 context
可以是 Scaffold
下的 context
,所以不需要用 Builder
来包裹一层。
1 | _showAlertDialog() { |
最后看下效果:
SimpleDialog
SimpleDialog
相比于 AlertDialog
少了 content
和 action
参数,多了 children
属性,需要传入 Widget
列表,那就可以自定义全部内容了。那我们这里就实现一个性别选择的 Dialog
,选择后通过 Taost
提示选择的内容,Taost
就是之前导入的第三方插件,先看下效果图吧
只要实现 children
是个列表选择器就可以了,比较简单,直接上代码
1 | _showSimpleDialog() { |
AboutDialog
AboutDialog
主要是用于展示你的 App
或者别的相关东西的内容信息的,平时用的比较少,显示 AboutDialog
有两种方式可以展示,一种是前面一样的 showDialog
方法,传入一个 AboutDialog
实例,还有中方法是直接调用 showAboutDialog
方法。我们还是一样在列表加个按钮,并指向显示 AboutDialog
的事件。
1 | _showAboutDialog() { |
也可以通过 showAboutDialog
实现同样的效果
1 | _showAboutDialog() { |
最后的效果:
AboutDialog
会自带两个按钮 VIEW LICENSES
和 CLOSE
,VIEW LICENSES
会跳转一个 Flutter Licenses
的网页,CLOSE
会关闭,至于为什么是英文的,是因为我们没有设置语言的原因,这个涉及到多语言,这边推荐几篇之前看过的文章,如果下次有时间的话会单独拿出来讲下
这边为了支持中文,我们做下如下的修改,首先打开 pubspec.ymal
文件加入如下支持
get package
后给 MaterialApp
加入如下属性,这样就会支持中文了,这里需要导入包 package:flutter_localizations/flutter_localizations.dart
,再次运行,就会发现之前的英文变成中文了,当然你也可以设置成别的语言。
Dialog 状态保持
假如有个需求,需要在弹出的 Dialog
显示当前被改变的值,然后通过按钮可以修改这个值 ,该如何实现。相信很多小伙伴都会这么认为,通过 setState
来修改不就行了吗,没错,我一开始的确这么去实现的,我们先看下代码好了,增加一个 DialogState
按钮,然后指向对应的点击事件
1 | _showStateDialog() { |
然后我们运行看下
诶诶诶,怎么 Dialog
的值不改变呢,明明界面上的已经修改了啊。所以说图样图森破咯,看下官方对 showDialog
方法的解释吧
1 | // This function takes a `builder` which typically builds a [Dialog] widget. |
糟糕透的翻译又来了:该方法通过 builder
参数来传入一个 Dialog
部件,dialog
下的内容被一个「模态障碍」阻隔,builder
的 context
和调用 showDialog
时候的 context
不是共享的,如果需要动态修改 dialog
的状态值,需要通过 StatefulBuilder
或者自定义 dialog
继承于 StatefulWidget
来实现
所以解决的方法很明确,对上面的代码进行修改,在外层嵌套一个 StatefulBuilder
部件
1 | _showStateDialog() { |
然后再运行下,可以看到 dialog
和界面的值保持一致了
以上部分代码查看 prompt_main.dart 文件
差不多常用弹窗和操作提示就在这了,好好消化吧~