You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BottomSheet中多Checkbox状态更新后界面不勾选问题排查

问题分析与解决方案

错误根源

  1. 选中状态变量作用域错误:_checkedState定义在BlocBuilder的builder回调内部,每次builder执行(比如外部setState触发、Bloc状态变化)都会重新初始化这个列表,之前的选中状态会直接丢失。
  2. 状态刷新范围不匹配:Checkbox的setState()调用的是外部Widget的状态刷新,但BottomSheet是独立的弹窗路由,外部的setState无法触发BottomSheet内部的UI更新,即使能触发,_checkedState也已经被重置为初始值。

修复方案

将选中状态的管理移到FutureBottomSheetStateful的内部State中,让BottomSheet自行维护选中状态,确保点击Checkbox时的setState能直接刷新弹窗内的UI。

1. 修改FutureBottomSheetStateful组件

class FutureBottomSheetStateful<T> extends StatefulWidget with BaseBottomSheetMixin {
  const FutureBottomSheetStateful(
      {required this.future,
      required this.itemBuilder,
      this.title = "",
      this.onItemSelected,
      this.initialCheckedStates,
      Key? key})
      : super(key: key);

  final String title;
  final Future<List<T>> Function() future;
  final Function(T)? onItemSelected;
  // 修改itemBuilder,传入选中状态及更新回调
  final Widget Function(BuildContext context, T item, int index, bool isChecked, Function(bool) onCheckedChanged) itemBuilder;
  final List<bool>? initialCheckedStates;

  @override
  State<FutureBottomSheetStateful<T>> createState() => _FutureBottomSheetStatefulState<T>();

  @override
  Widget build(BuildContext context) => this;
}

class _FutureBottomSheetStatefulState<T> extends State<FutureBottomSheetStateful<T>> {
  late List<bool> _checkedStates;

  @override
  void initState() {
    super.initState();
    _checkedStates = widget.initialCheckedStates ?? [];
  }

  @override
  void didUpdateWidget(covariant FutureBottomSheetStateful<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.initialCheckedStates != null && widget.initialCheckedStates != oldWidget.initialCheckedStates) {
      setState(() {
        _checkedStates = widget.initialCheckedStates!;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    var child = FutureBuilder<List<T>>(
        future: widget.future(),
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            // 确保选中状态列表长度与数据一致
            if (_checkedStates.length != snapshot.data!.length) {
              _checkedStates = List.filled(snapshot.data!.length, false);
              if (widget.initialCheckedStates != null && widget.initialCheckedStates!.length == snapshot.data!.length) {
                _checkedStates = List.from(widget.initialCheckedStates!);
              }
            }
            return ListView.builder(
                physics: const PageScrollPhysics(),
                shrinkWrap: true,
                itemCount: snapshot.data!.length,
                itemBuilder: (context, index) {
                  var item = snapshot.data![index];
                  return InkWell(
                    onTap: () {
                      if (widget.onItemSelected != null) {
                        widget.onItemSelected!(item);
                      } else {
                        context.pop(item);
                      }
                    },
                    // 传递选中状态和更新回调给itemBuilder
                    child: widget.itemBuilder(context, item, index, _checkedStates[index], (value) {
                      setState(() {
                        _checkedStates[index] = value;
                        Log.e("chs", _checkedStates[index].toString());
                      });
                    }),
                  );
                });
          }
          if (snapshot.hasError) {
            return const PassErrorWidget();
          }
          return const PassLoadingWidget();
        });

    return BaseBottomSheet(title: widget.title, child: child);
  }
}

2. 修改BlocBuilder中的调用代码

BlocBuilder<PaymentApprovalCubit, SettingsFetchState>(
  builder: (context, membersState){
    if(membersState is SettingsFetchLoaded){
      return ClickableFormField(
        hintText: "Select an option",
        onPressed: () async {
          final TeamMembersResponse? result =
          await FutureBottomSheetStateful<TeamMembersResponse>(
            future: () => Future.value(membersState.data),
            itemBuilder: (context, item, index, isChecked, onCheckedChanged) {
              return Padding(
                  padding: const EdgeInsets.symmetric(
                    vertical: 14,
                    horizontal: 8,
                  ),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.start,
                    crossAxisAlignment: CrossAxisAlignment.center,
                    children: [
                      Checkbox(
                        checkColor: AppColors.passBlack,
                        activeColor: AppColors.passBlack.withOpacity(0.1),
                        value: isChecked,
                        onChanged: (value) {
                          onCheckedChanged(value!);
                        },
                      ),
                      Column(
                        mainAxisAlignment: MainAxisAlignment.start,
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            "${item.firstName} ${item.lastName}",
                            style: context.textTheme.bodyMedium?.copyWith(fontSize: 14).bold,
                          ),
                          Text(
                            item.email??"",
                            style: const TextStyle(
                                color: AppColors.greySubTitle,
                                fontSize: 12
                            ),
                          )
                        ],
                      )
                    ],
                  )
              );
            },
          ).show(context);
          setState(() {
            if (result != null) {
              // 此处可添加选中后的业务逻辑
            }
          });
        },
      );
    }
    return const SizedBox.shrink();
  },
),

内容的提问来源于stack exchange,提问作者ibramazin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 19:55:15