BottomSheet 是一个 Material Design StatefulWidget。我们很少直接使用他,而是通过 showBottomSheet 和 showModalBottomSheet 使用他。
showBottomSheet 用法
PersistentBottomSheetController<T> showBottomSheet<T>({ required BuildContext context, required WidgetBuilder builder, Color? backgroundColor, double? elevation, ShapeBorder? shape, Clip? clipBehavior, BoxConstraints? constraints, bool? enableDrag, AnimationController? transitionAnimationController, }) 复制代码
backgroundColor 是 bottomSheet 的背景色,默认是不透明的,要想透明可以设置为 Colors.transparent
。elevation 基本上看不到什么效果,因为 elevation 大多在底下,如果不想用矩形可以指定 shape。比如指定为圆形 shape: CircleBorder()
,也可以设置为圆角,shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30))
,圆角可能用的更多些。
showModalBottomSheet( context: context, shape: RoundedRectangleBorder( borderRadius: BorderRadius.vertical(top: Radius.circular(30))), builder: ((context) { return Container( decoration: BoxDecoration( border: Border.all(width: 3, color: Colors.green)), height: 100, ); })); 复制代码
虽然 shape 为 圆角,但 child 仍然可以在 shape 之外绘制,好像 shape 没有设置一样。需要自己注意,在远离边缘的地方绘制 child,用 ClipRRect 也可以。
enableDrag 默认为 true,可以拖动改变 BottomSheet 的高度。一直往下拖可以让 BottomSheet 消失。如果 enableDrag 是 false 就无法拖动了。
一般情况下用默认值就可以了。showBottomSheet 默认没有 padding。
showBottomSheet( context: context, builder: ((context) { return Container( height: 300, ); })); 复制代码
这种由 showBottomSheet 方法弹出的 sheet 是 persistent sheet。是和 modal 相对而言的。persistent sheet 允许用户和 sheet 之外的 UI 交互,modal 不允许用户和 sheet 之外的 UI 交互。
showModalBottomSheet 用法
Future<T?> showModalBottomSheet<T>({ required BuildContext context, required WidgetBuilder builder, Color? backgroundColor, double? elevation, ShapeBorder? shape, Clip? clipBehavior, BoxConstraints? constraints, Color? barrierColor, bool isScrollControlled = false, bool useRootNavigator = false, bool isDismissible = true, bool enableDrag = true, RouteSettings? routeSettings, AnimationController? transitionAnimationController, Offset? anchorPoint, }) 复制代码
与 showBottomSheet 相比,多了 barrierColor,是蒙层的颜色。不是不让用户与 sheet 之外的 UI 交互吗?办法就是蒙起来。isDismissible 为 true ,点蒙层可以关闭 sheet。anchorPoint 分屏用的,暂时用不到,分屏的场景暂时还太少了。RouteSettings 用于路由监听,因为 bottomSheet 也是一个路由。isScrollControlled 如果设置为true,当 child 为 ListView,GridView 等滚动 widget 的时候,可以全屏。
使用的时候也是直接用默认值就好了。
showModalBottomSheet( context: context, builder: ((context) { return Container( height: 300, ); }));