show<T> static method

Future<T?> show<T>(
  1. BuildContext context,
  2. Widget child, {
  3. double? height,
  4. bool fullScreen = false,
  5. bool draggableScrollable = false,
  6. double initialChildSize = 0.5,
  7. double minChildSize = 0.25,
  8. double maxChildSize = 1.0,
  9. bool snap = false,
  10. List<double>? snapSizes,
  11. bool enableDrag = true,
  12. bool isDismissible = true,
  13. bool showDragHandle = true,
  14. double? borderRadius,
  15. Color? backgroundColor,
  16. Color? barrierColor,
  17. EdgeInsetsGeometry? padding,
  18. VoidCallback? onDismiss,
})

显示底部弹出面板

context 上下文 child 面板内容

高度控制: height 固定高度,不传则自适应内容(最大450) fullScreen 是否全屏,优先级高于 height

拖拽伸缩模式(优先级最高): draggableScrollable 是否启用可拖拽伸缩模式(从半屏拖到全屏) initialChildSize draggable模式的初始高度占比,默认 0.5(半屏) minChildSize draggable模式的最小高度占比,默认 0.25 maxChildSize draggable模式的最大高度占比,默认 1.0(全屏)

弹性吸附(仅 draggableScrollable 模式生效): snap 开启后松手自动吸附到最近档位(高德首页那种弹性效果),默认 false(拖到哪停哪) snapSizes 中间吸附档位列表(占比),如 0.5;min/maxChildSize 会自动作为吸附点,不要在此重复

交互行为: enableDrag 是否允许向下拖拽关闭,默认 true isDismissible 点击遮罩是否关闭,默认 true showDragHandle 是否显示顶部拖拽手柄(小横条),默认 true

样式定制: borderRadius 顶部圆角,默认从主题读取 dialogRadius backgroundColor 面板背景色,默认从主题读取 surface 色 barrierColor 遮罩颜色 padding child 内边距,默认 16

回调: onDismiss 面板关闭回调

示例:

// 固定高度
VBottomSheet.show(context, MyWidget(), height: 400);

// 全屏
VBottomSheet.show(context, MyWidget(), fullScreen: true);

// 可拖拽伸缩(半屏到全屏)
VBottomSheet.show(
  context,
  ListView(...),
  draggableScrollable: true,
  initialChildSize: 0.6,
);

// 弹性吸附(高德首页效果:松手吸附到最近档位)
VBottomSheet.show(
  context,
  ListView(...),
  draggableScrollable: true,
  snap: true,
  snapSizes: [0.5],   // 中间档位,min/max 自动成为吸附点 → 三档吸附
  initialChildSize: 0.5,
);

Implementation

static Future<T?> show<T>(
  BuildContext context,
  Widget child, {
  // 高度控制
  double? height,
  bool fullScreen = false,
  // 拖拽伸缩模式
  bool draggableScrollable = false,
  double initialChildSize = 0.5,
  double minChildSize = 0.25,
  double maxChildSize = 1.0,
  // 弹性吸附(仅 draggableScrollable 模式生效)
  bool snap = false,
  List<double>? snapSizes,
  // 交互行为
  bool enableDrag = true,
  bool isDismissible = true,
  bool showDragHandle = true,
  // 样式定制
  double? borderRadius,
  Color? backgroundColor,
  Color? barrierColor,
  EdgeInsetsGeometry? padding,
  // 回调
  VoidCallback? onDismiss,
}) {
  // 计算实际高度
  double? effectiveHeight;
  if (draggableScrollable) {
    // 拖拽伸缩模式不需要固定高度
    effectiveHeight = null;
  } else if (fullScreen) {
    // 全屏模式
    effectiveHeight = MediaQuery.of(context).size.height;
  } else {
    // 固定高度或自适应
    effectiveHeight = height;
  }

  return showModalBottomSheet<T>(
    context: context,
    isScrollControlled: true,
    // 关键:允许自定义高度
    isDismissible: isDismissible,
    enableDrag: enableDrag,
    backgroundColor: Colors.transparent,
    // 外层透明,让内部圆角生效
    barrierColor: barrierColor,
    builder: (context) {
      // 根据是否拖拽伸缩模式选择不同的包裹方式
      if (draggableScrollable) {
        return DraggableScrollableSheet(
          initialChildSize: initialChildSize,
          minChildSize: minChildSize,
          maxChildSize: maxChildSize,
          snap: snap,
          // 开启后松手自动吸附到最近档位
          snapSizes: snapSizes,
          // 吸附档位列表,null 时吸附到 min/max
          builder: (context, scrollController) {
            return VBottomSheetContent(
              child: child,
              showDragHandle: showDragHandle,
              borderRadius: borderRadius,
              backgroundColor: backgroundColor,
              padding: padding,
              scrollController: scrollController,
            );
          },
        );
      } else {
        // 固定高度或自适应模式
        return VBottomSheetContent(
          child: child,
          height: effectiveHeight,
          showDragHandle: showDragHandle,
          borderRadius: borderRadius,
          backgroundColor: backgroundColor,
          padding: padding,
        );
      }
    },
  ).then((value) {
    // 面板关闭时触发回调
    onDismiss?.call();
    return value;
  });
}