BottomSheet 是从底部弹出来的对话框,总共分为两种,而且每种的使用方式都不同:

  1. PersistentBottomSheet:持续的底部对话框持续的 BottomSheet,当 BottomSheet 弹出时,会一直覆盖在 APP 的界面上,而且背景是透明的,所以你还可以和界面有其他交互,且点击背景不能让 PersistentBottomSheet 消失。除非点击返回,PersistentBottomSheet 才会消失。PersistentBottomSheet 的创建和显示的方法:
    • 可以用 Scaffold 的 showBottomSheet() 方法
    • 也可以设置 Scaffold 的 bottomSheet 参数。
  2. ModalBottomSheet:有半透明背景的对话框ModalBottomSheet 类似一个 Dialog,有一个半透明的背景层,点击背景,ModalBottomSheet 会消失。ModalBottomSheet 的创建和显示的方法:
    • 只能使用 showModalBottomSheet() 方法。

在使用显示 BottomSheet 的方法的时候,必须要注意这些方法只能在 Scaffold 的 子Widget 里使用,因为这些方法需要用到 Scaffold 的 Context,如果和 Scaffold 在同一层,那么就要使用 Builder。

BottomSheet

这里先介绍一下 BottomSheet,然后在介绍使用方法。

BottomSheet 的构造函数及参数说明

BottomSheet 的构造函数为:

  1. class BottomSheet extends StatefulWidget {
  2. const BottomSheet({
  3. Key key,
  4. this.animationController,
  5. this.enableDrag = true,
  6. this.elevation = 0.0,
  7. @required this.onClosing,
  8. @required this.builder
  9. })
  10. ...
  11. }
参数名字 参数类型 意义 必选 or 可选
key Key Widget 的标识 可选
animationController AnimationController 控制 BottomSheet 的动画 可选
enableDrag bool BottomSheet 是否可以拖动
默认为true,可以向上拖、向下拖或者向下滑动关闭 BottomSheet
可选
elevation double BottomSheet 相对于其父级放置的z坐标,这可以控制 BottomSheet 的阴影大小
默认值为0.0,该值必须>=0
可选
onClosing VoidCallback 当 BottomSheet 关闭的时候调用
这个事件可能会多次调用
必选
builder WidgetBuilder BottomSheet 要显示的内容 必选

PersistentBottomSheet:持续的底部对话框

PersistentBottomSheet 的创建和显示的方法:

  1. 可以用 Scaffold 的 showBottomSheet() 方法
  2. 也可以设置 Scaffold 的 bottomSheet 参数。

showBottomSheet()

showBottomSheet() 方法的定义及参数说明

showBottomSheet() 方法的定义为:

  1. PersistentBottomSheetController<T> showBottomSheet<T>({
  2. @required BuildContext context,
  3. @required WidgetBuilder builder,
  4. }) {
  5. assert(context != null);
  6. assert(builder != null);
  7. return Scaffold.of(context).showBottomSheet<T>(builder);
  8. }
参数名字 参数类型 意义 必选 or 可选
context BuildContext 应用上下文 必选
builder WidgetBuilder 要显示的 BottomSheet 必选

showBottomSheet() 的使用

showBottomSheet() 使用的完整 Demo 如下:

  1. import 'package:flutter/material.dart';
  2. main() => runApp(new ShowPersistentBottomSheetWidget());
  3. class ShowPersistentBottomSheetWidget extends StatelessWidget {
  4. @override
  5. Widget build(BuildContext context) {
  6. return new MaterialApp(
  7. title: 'Test',
  8. home: new Scaffold(
  9. appBar:
  10. new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
  11. body: Builder(
  12. builder: (context) {
  13. return RaisedButton(
  14. onPressed: () {
  15. showBottomSheet(
  16. context: context,
  17. builder: (context) => BottomSheet(
  18. onClosing: () {},
  19. builder: (context) => Container(
  20. height: 200.0,
  21. color: Colors.blue,
  22. child: Center(
  23. child: RaisedButton(
  24. onPressed: () {
  25. Navigator.of(context).pop();
  26. },
  27. child: Text('dismissBottomSheet'),
  28. ),
  29. ),
  30. )));
  31. },
  32. child: Text('showBottomSheet'),
  33. );
  34. },
  35. )),
  36. );
  37. }
  38. }

运行后的效果为:
Flutter 学习(十六)基础 Widget - BottomSheet - 图1

  • PersistentBottomSheet 的关闭
    PersistentBottomSheet 出现时,TitleBar 的右上角会多一个返回的按钮,可以关闭 PersistentBottomSheet,因为 PersistentBottomSheet 无法通过点击背景关闭。
    或者在 BottomSheet 里使用 Navigator.of(context).pop(); 来关闭 PersistentBottomSheet。

Scaffold 的 bottomSheet 参数

就是直接给 Scaffold 的 bottomSheet 参数赋 BottomSheet 的实例,这样 Scaffold 一创建的时候就会显示 BottomSheet。

bottomSheet 的使用

完整 Demo 如下:

  1. import 'package:flutter/material.dart';
  2. main() => runApp(new PersistentBottomSheetWidgetWidget());
  3. class PersistentBottomSheetWidgetWidget extends StatelessWidget {
  4. @override
  5. Widget build(BuildContext context) {
  6. return new MaterialApp(
  7. title: 'Test',
  8. home: new Scaffold(
  9. appBar: new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
  10. body: Builder(
  11. builder: (context) {
  12. return RaisedButton(
  13. onPressed: () {},
  14. child: Text('showBottomSheet'),
  15. );
  16. },
  17. ),
  18. bottomSheet: BottomSheet(
  19. onClosing: () {},
  20. builder: (context) => Container(
  21. height: 200.0,
  22. color: Colors.blue,
  23. child: Center(
  24. child: RaisedButton(
  25. onPressed: () {
  26. Navigator.of(context).pop();
  27. },
  28. child: Text('dismissBottomSheet'),
  29. ),
  30. ),
  31. )),
  32. ),
  33. );
  34. }
  35. }

运行效果和上面的一样。

ModalBottomSheet:有半透明背景的对话框

ModalBottomSheet 的创建和显示的方法:

  • 只能使用 showModalBottomSheet() 方法。

showModalBottomSheet() 方法的定义及参数说明

showModalBottomSheet() 方法的定义如下:

  1. Future<T> showModalBottomSheet<T>({
  2. @required BuildContext context,
  3. @required WidgetBuilder builder,
  4. }) {
  5. assert(context != null);
  6. assert(builder != null);
  7. assert(debugCheckHasMaterialLocalizations(context));
  8. return Navigator.push(context, _ModalBottomSheetRoute<T>(
  9. builder: builder,
  10. theme: Theme.of(context, shadowThemeOnly: true),
  11. barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
  12. ));
  13. }
参数名字 参数类型 意义 必选 or 可选
context BuildContext 应用上下文 必选
builder WidgetBuilder 要显示的 BottomSheet 必选

showModalBottomSheet() 的使用

可以看到 showModalBottomSheet() 和 showBottomSheet() 的参数一样,所以使用方法也一样,直接把第一个 Demo 里的方法名替换为 showModalBottomSheet()。

完整 Demo 如下:

  1. import 'package:flutter/material.dart';
  2. main() => runApp(new ShowModalBottomSheetWidget());
  3. class ShowModalBottomSheetWidget extends StatelessWidget {
  4. @override
  5. Widget build(BuildContext context) {
  6. return new MaterialApp(
  7. title: 'Test',
  8. home: new Scaffold(
  9. appBar:
  10. new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
  11. body: Builder(
  12. builder: (context) {
  13. return RaisedButton(
  14. onPressed: () {
  15. showModalBottomSheet(
  16. context: context,
  17. builder: (context) => BottomSheet(
  18. onClosing: () {},
  19. builder: (context) => Container(
  20. height: 200.0,
  21. color: Colors.blue,
  22. child: Center(
  23. child: RaisedButton(
  24. onPressed: () {
  25. Navigator.of(context).pop();
  26. },
  27. child: Text('dismissBottomSheet'),
  28. ),
  29. ),
  30. )));
  31. },
  32. child: Text('showBottomSheet'),
  33. );
  34. },
  35. )),
  36. );
  37. }
  38. }

运行效果为:
Flutter 学习(十六)基础 Widget - BottomSheet - 图2
可以看到 ModalBottomSheet 弹出来时,背景是半透明的,点击半透明的背景也能关闭 ModalBottomSheet。

参考

【1】Flutter 实战
【2】Flutter 中文文档
【3】Flutter 完全手册