BottomSheet 是从底部弹出来的对话框,总共分为两种,而且每种的使用方式都不同:
- PersistentBottomSheet:持续的底部对话框持续的 BottomSheet,当 BottomSheet 弹出时,会一直覆盖在 APP 的界面上,而且背景是透明的,所以你还可以和界面有其他交互,且点击背景不能让 PersistentBottomSheet 消失。除非点击返回,PersistentBottomSheet 才会消失。PersistentBottomSheet 的创建和显示的方法:
- 可以用 Scaffold 的
showBottomSheet()
方法 - 也可以设置 Scaffold 的
bottomSheet
参数。
- 可以用 Scaffold 的
- ModalBottomSheet:有半透明背景的对话框ModalBottomSheet 类似一个 Dialog,有一个半透明的背景层,点击背景,ModalBottomSheet 会消失。ModalBottomSheet 的创建和显示的方法:
- 只能使用
showModalBottomSheet()
方法。
- 只能使用
在使用显示 BottomSheet 的方法的时候,必须要注意这些方法只能在 Scaffold 的 子Widget 里使用,因为这些方法需要用到 Scaffold 的 Context,如果和 Scaffold 在同一层,那么就要使用 Builder。
BottomSheet
这里先介绍一下 BottomSheet,然后在介绍使用方法。
BottomSheet 的构造函数及参数说明
BottomSheet 的构造函数为:
class BottomSheet extends StatefulWidget {
const BottomSheet({
Key key,
this.animationController,
this.enableDrag = true,
this.elevation = 0.0,
@required this.onClosing,
@required this.builder
})
...
}
参数名字 | 参数类型 | 意义 | 必选 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 的创建和显示的方法:
- 可以用 Scaffold 的
showBottomSheet()
方法 - 也可以设置 Scaffold 的
bottomSheet
参数。
showBottomSheet()
showBottomSheet() 方法的定义及参数说明
showBottomSheet() 方法的定义为:
PersistentBottomSheetController<T> showBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
}) {
assert(context != null);
assert(builder != null);
return Scaffold.of(context).showBottomSheet<T>(builder);
}
参数名字 | 参数类型 | 意义 | 必选 or 可选 |
---|---|---|---|
context | BuildContext | 应用上下文 | 必选 |
builder | WidgetBuilder | 要显示的 BottomSheet | 必选 |
showBottomSheet() 的使用
showBottomSheet() 使用的完整 Demo 如下:
import 'package:flutter/material.dart';
main() => runApp(new ShowPersistentBottomSheetWidget());
class ShowPersistentBottomSheetWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Test',
home: new Scaffold(
appBar:
new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
body: Builder(
builder: (context) {
return RaisedButton(
onPressed: () {
showBottomSheet(
context: context,
builder: (context) => BottomSheet(
onClosing: () {},
builder: (context) => Container(
height: 200.0,
color: Colors.blue,
child: Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('dismissBottomSheet'),
),
),
)));
},
child: Text('showBottomSheet'),
);
},
)),
);
}
}
运行后的效果为:
- PersistentBottomSheet 的关闭
PersistentBottomSheet 出现时,TitleBar 的右上角会多一个返回的按钮,可以关闭 PersistentBottomSheet,因为 PersistentBottomSheet 无法通过点击背景关闭。
或者在 BottomSheet 里使用Navigator.of(context).pop();
来关闭 PersistentBottomSheet。
Scaffold 的 bottomSheet 参数
就是直接给 Scaffold 的 bottomSheet 参数赋 BottomSheet 的实例,这样 Scaffold 一创建的时候就会显示 BottomSheet。
bottomSheet 的使用
完整 Demo 如下:
import 'package:flutter/material.dart';
main() => runApp(new PersistentBottomSheetWidgetWidget());
class PersistentBottomSheetWidgetWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Test',
home: new Scaffold(
appBar: new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
body: Builder(
builder: (context) {
return RaisedButton(
onPressed: () {},
child: Text('showBottomSheet'),
);
},
),
bottomSheet: BottomSheet(
onClosing: () {},
builder: (context) => Container(
height: 200.0,
color: Colors.blue,
child: Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('dismissBottomSheet'),
),
),
)),
),
);
}
}
运行效果和上面的一样。
ModalBottomSheet:有半透明背景的对话框
ModalBottomSheet 的创建和显示的方法:
- 只能使用
showModalBottomSheet()
方法。
showModalBottomSheet() 方法的定义及参数说明
showModalBottomSheet() 方法的定义如下:
Future<T> showModalBottomSheet<T>({
@required BuildContext context,
@required WidgetBuilder builder,
}) {
assert(context != null);
assert(builder != null);
assert(debugCheckHasMaterialLocalizations(context));
return Navigator.push(context, _ModalBottomSheetRoute<T>(
builder: builder,
theme: Theme.of(context, shadowThemeOnly: true),
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
));
}
参数名字 | 参数类型 | 意义 | 必选 or 可选 |
---|---|---|---|
context | BuildContext | 应用上下文 | 必选 |
builder | WidgetBuilder | 要显示的 BottomSheet | 必选 |
showModalBottomSheet() 的使用
可以看到 showModalBottomSheet() 和 showBottomSheet() 的参数一样,所以使用方法也一样,直接把第一个 Demo 里的方法名替换为 showModalBottomSheet()。
完整 Demo 如下:
import 'package:flutter/material.dart';
main() => runApp(new ShowModalBottomSheetWidget());
class ShowModalBottomSheetWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Test',
home: new Scaffold(
appBar:
new AppBar(title: new Text('Flutter UI Widget -- BottomSheet')),
body: Builder(
builder: (context) {
return RaisedButton(
onPressed: () {
showModalBottomSheet(
context: context,
builder: (context) => BottomSheet(
onClosing: () {},
builder: (context) => Container(
height: 200.0,
color: Colors.blue,
child: Center(
child: RaisedButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('dismissBottomSheet'),
),
),
)));
},
child: Text('showBottomSheet'),
);
},
)),
);
}
}
运行效果为:
可以看到 ModalBottomSheet 弹出来时,背景是半透明的,点击半透明的背景也能关闭 ModalBottomSheet。
参考
【1】Flutter 实战
【2】Flutter 中文文档
【3】Flutter 完全手册