Flutter-底部选择弹窗(showModalBottomSheet)

前言

现在有个需求,需要用底部弹窗来添加定时的重复。在这里使用原生的showModalBottomSheet来实现

showModalBottomSheet的Props

名称 描述
isScrollControlled 全屏还是半屏
isDismissible 外部是否可以点击,false不可以点击,true可以点击,点击后消失
backgroundColor 背景色,通常可以设置白色和透明
barrierColor 设置遮挡底部的半透明颜色,默认是black54,可以设置成透明的; 置外部区域的颜色
enableDrag 是否可以向下拖动关闭,默认是true打开的;
shape model边框样式
builder 构造内容

关闭弹窗

Navigator.pop(context);

完整代码

showModalBottomSheet(
      context: context,
      backgroundColor: Colors.transparent,
      builder: (context) {
        return Container(
          height: 600.h,
          padding: EdgeInsets.symmetric(horizontal: 30.w),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.only(
              topLeft: Radius.circular(30.w),
              topRight: Radius.circular(30.w),
            ),
            color: Colors.white,
          ),
          child: Column(
            children: [
              Container(
                height: 110.h,
                child: Center(
                  child: Text(
                    "重复".tr,
                    style: TextStyle(
                      fontSize: 30.sp,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
              RepeatModelItem(
                title: "启动一次".tr,
                isSelect: repeatDate.isEmpty,
                onPressed: () {
                   Navigator.pop(context);
                 
                },
              ),
              RepeatModelItem(
                title: "每天".tr,
                isSelect: repeatDate.length == 7,
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
              RepeatModelItem(
                title: "自定义".tr,
                isSelect: repeatDate.isNotEmpty && repeatDate.length < 7,
                onPressed: () {
                  Navigator.pop(context);
                },
              ),
              Container(
                margin: EdgeInsets.only(top: 20.h),
                child: TextButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text("取消".tr),
                ),
              )
            ],
          ),
        );
      },
    );

但是此时遇到了一个问题,在底部选择中使用多选框的是否不能选中

解决办法

使用StatefulBuilder实现局部刷新

showModalBottomSheet(
      isScrollControlled: true,
      context: context,
      backgroundColor: Colors.transparent,
      builder: (context) {
        //因为组件中用了多选框,要使多选框点击生效,所以这里使用了StatefulBuilder,实现局部刷新
        return StatefulBuilder(
          //弹窗内容
          builder: (context, setState) {
            return Container(
              height: 1050.h,
              padding: EdgeInsets.symmetric(horizontal: 30.w),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.only(
                  topLeft: Radius.circular(30.w),
                  topRight: Radius.circular(30.w),
                ),
                color: Colors.white,
              ),
              child: Column(
                children: [
                  // 标题
                  SizedBox(
                    height: 110.h,
                    child: Center(
                      child: Text(
                        "自定义".tr,
                        style: TextStyle(
                          fontSize: 30.sp,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ),
                  ),
                  RepeatModelItem(
                    title: "周一".tr,
                    isSelect: customrepeatDate[0] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[0] = customrepeatDate[0] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周二".tr,
                    isSelect: customrepeatDate[1] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[1] = customrepeatDate[1] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周三".tr,
                    isSelect: customrepeatDate[2] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[2] = customrepeatDate[2] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周四".tr,
                    isSelect: customrepeatDate[3] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[3] = customrepeatDate[3] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周五".tr,
                    isSelect: customrepeatDate[4] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[4] = customrepeatDate[4] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周六".tr,
                    isSelect: customrepeatDate[5] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[5] = customrepeatDate[5] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  RepeatModelItem(
                    title: "周日".tr,
                    isSelect: customrepeatDate[6] == 1,
                    onPressed: () {
                      setState(() {
                        customrepeatDate[6] = customrepeatDate[6] == 1 ? 0 : 1;
                      });
                    },
                  ),
                  // 取消、确定按钮
                  Container(
                    margin: EdgeInsets.only(top: 20.h),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: [
                        // 取消按钮
                        TextButton(
                          style: TextButton.styleFrom(
                            minimumSize: Size(300.w, 80.h),
                          ),
                          onPressed: () {
                            setState(() {
                              customrepeatDate =
                                  setcustomrepeatDate(repeatDate);
                            });
                            Navigator.pop(context);
                          },
                          child: Text("取消".tr),
                        ),
                        // 确定按钮
                        TextButton(
                          style: TextButton.styleFrom(
                            minimumSize: Size(300.w, 80.h),
                          ),
                          onPressed: () {
                            var repeatDate1 = [];
                            for (var i = 0; i < 7; i++) {
                              if (customrepeatDate[i] == 1) {
                                repeatDate1.add(i + 1);
                              }
                            }
                            // setState(() {
                            //   repeatDate = repeatDate1;
                            // });
                            //用上面的方法我更新不了repeatDate数据,于是我将更新放在外面了,可能是setState是StatefulBuilder的
                            setRepeatDate(repeatDate1);
                            Navigator.pop(context);
                          },
                          child: Text("确定".tr),
                        ),
                      ],
                    ),
                  )
                ],
              ),
            );
          },
        );
      },
    );
相关推荐
crasowas2 小时前
Flutter问题记录 - 适配Xcode 16和iOS 18
flutter·ios·xcode
老田低代码1 天前
Dart自从引入null check后写Flutter App总有一种难受的感觉
前端·flutter
AiFlutter1 天前
Flutter Web首次加载时添加动画
前端·flutter
ZemanZhang3 天前
Flutter启动无法运行热重载
flutter
帅次4 天前
Android Studio:驱动高效开发的全方位智能平台
android·ide·flutter·kotlin·gradle·android studio·android jetpack
程序者王大川4 天前
【前端】Flutter vs uni-app:性能对比分析
前端·flutter·uni-app·安卓·全栈·性能分析·原生
yang2952423614 天前
使用 Vue.js 将数据对象的值放入另一个数据对象中
前端·vue.js·flutter
我码玄黄4 天前
解锁定位服务:Flutter应用中的高德地图定位
前端·flutter·dart
hudawei9964 天前
flutter widget 设置GestureDetector点击无效
flutter·gesturedetector·点击事件