话不多说,直接上代码。
class BottomSheetUtils {
BottomSheetUtils.showBottomSheet(
BuildContext context, {
required Widget child,
double? height, //固定高度
double? maxHeight, //最大高度
double minHeight = 213, //最小高度
double statusBarHeight = 0, //状态栏高度
double bottomBarHeight = 0, //底部bar高度
double appBarHeight = 0, //appbar的高度
Widget? titleView, // 弹窗顶部标题
double titleHeight = 50, //弹窗顶部标题高度
}) {
_bottomSheet(
context,
child: child,
height: height,
maxHeight: maxHeight,
minHeight: minHeight,
statusBarHeight: statusBarHeight,
bottomBarHeight: bottomBarHeight,
appBarHeight: appBarHeight,
titleView: titleView,
titleHeight: titleHeight,
);
}
///自适应高度底部弹窗
void _bottomSheet(
BuildContext context, {
required Widget child,
double? height, //固定高度
double? maxHeight, //最大高度
double minHeight = 213, //最小高度
double statusBarHeight = 0, //状态栏高度
double bottomBarHeight = 0, //底部bar高度
double appBarHeight = 0, //appbar的高度
Widget? titleView, // 弹窗顶部标题
double titleHeight = 50, //弹窗顶部标题高度
}) {
///如果maxHeight没有设置值,则高度为默认去除statusBarHeight高度与title高度
maxHeight ??= Get.height -
statusBarHeight -
appBarHeight -
(titleView == null ? 0 : titleHeight);
Widget widget;
if (child is ScrollView) {
/// 如果height没有设置值,则默认为最大高度
height ??= maxHeight;
widget = child;
} else {
widget = SingleChildScrollView(
child: child,
);
}
if (titleView == null) {
/// 没有title
widget = Container(
height: height,
padding: EdgeInsets.only(bottom: bottomBarHeight),
decoration: const BoxDecoration(
///这里设置了背景色和圆角
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8), topRight: Radius.circular(8))),
constraints: BoxConstraints(maxHeight: maxHeight, minHeight: minHeight),
child: widget,
);
} else {
/// 有title
widget = Column(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Expanded(
child: Container(
color: Colors.transparent,
).onTap(() {
/// 这里的onTap是我的Widget做的一个扩展,如下:
/// extension WidgetExt on Widget {
/// Widget onTap(GestureTapCallback onTap) {
/// return GestureDetector(
/// onTap: onTap,
/// child: this,
/// );
/// }
/// }
Get.back(); // 点击空白区域关闭dialog,这里我用了Getx框架,可以修改为系统或者其他方式关闭弹框
})),
/// 此处为弹窗标题
titleView,
/// 以下为弹窗内容
Container(
height: height,
padding: EdgeInsets.only(bottom: bottomBarHeight),
color: Colors.white,
constraints: BoxConstraints(
maxHeight: maxHeight, minHeight: minHeight - titleHeight),
child: widget,
),
],
);
}
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
isDismissible: true,
isScrollControlled: true,
builder: (context) {
return widget;
});
}
}