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

Flutter AlertDialog内CheckboxListTile筛选ListView不生效问题

问题根因

弹窗内勾选复选框后外部列表不刷新,核心是3个代码逻辑问题:

  • StatefulBuilder提供的弹窗局部刷新方法setState和外层页面的setState同名,勾选时调用的是弹窗内部的刷新方法,只会更新弹窗内的复选框状态,根本不会触发外层商品列表所在页面的重绘
  • 分类模型的fromJson解析方法没有给isChecked字段赋值默认值,接口返回数据解析后该字段为null,会导致复选框状态异常
  • 把筛选逻辑直接写在build方法顶层,会导致无意义的重复执行,甚至触发循环刷新
相关资源
  • 商品列表数据接口:
https://run.mocky.io/v3/4ecbd2ea-a725-438b-b8fc-da8fc08bc875
  • 筛选分类列表接口:
https://run.mocky.io/v3/0595387e-732e-47cf-9675-244fed9fc014
  • 待筛选的ListView数据效果图:
    待筛选的ListView数据效果图
  • AlertDialog内的CheckboxListTile效果图:
    AlertDialog内的CheckboxListTile效果图
修复步骤

1. 修复分类模型解析逻辑

给ProductCategoryDataModel的fromJson方法补全isChecked的初始值,避免空值异常:

ProductCategoryDataModel.fromJson(Map<String, dynamic> json) {
  productCategoryId = json['ProductCategoryId'];
  productCategoryName = json['ProductCategoryName'];
  isChecked = false; // 补充该行
}

2. 区分弹窗与外层页面的刷新作用域

修改showDialog内StatefulBuilder的回调参数名,把内部刷新方法和外层页面的刷新方法区分开,勾选状态变化时同时触发弹窗内部刷新和外层页面刷新:

showDialog(
  context: context,
  builder: (BuildContext context) {
    return StatefulBuilder(
      // 把弹窗内部的setState重命名为setDialogState,避免和外层同名冲突
      builder: (context, setDialogState) {
        return AlertDialog(
          titlePadding: EdgeInsets.zero,
          backgroundColor: Color(0xFF242424),
          title: Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              IconButton(
                onPressed: () => Navigator.of(context).pop(),
                icon: Icon(Icons.close, color: Colors.white, size: 25)
              )
            ],
          ),
          contentPadding: EdgeInsets.zero,
          content: Container(
            padding: EdgeInsets.all(5),
            width: double.maxFinite,
            child: ListView(
              padding: EdgeInsets.all(8.0),
              children: [
                ...productCategoryDataList.map((e) => CheckboxListTile(
                  controlAffinity: ListTileControlAffinity.leading,
                  title: Text(
                    "${e.productCategoryName}",
                    style: TextStyle(color: Colors.white, fontSize: 16),
                  ),
                  value: e.isChecked,
                  selected: selectProductCategoryDataList.contains(e),
                  onChanged: (val) {
                    // 先刷新弹窗内部复选框状态
                    setDialogState(() {
                      e.isChecked = val;
                      selectProductCategoryDataList.contains(e)
                          ? selectProductCategoryDataList.remove(e)
                          : selectProductCategoryDataList.add(e);
                    });
                    // 重新计算筛选结果
                    filterProduct(productDataList);
                    // 触发外层页面重绘更新列表
                    setState(() {});
                  },
                ))
              ],
            ),
          ),
        );
      },
    );
  }
);

3. 调整筛选逻辑执行时机

删除原来写在build方法顶层的filterProduct(productDataList);调用,只在两个时机执行筛选逻辑:

  • 商品列表、分类列表接口全部请求完成后,调用一次filterProduct初始化全量商品展示
  • 弹窗内复选框状态变化时,主动调用filterProduct重新计算结果
    该调整可以避免build每次触发都重复执行筛选计算,减少无意义的性能损耗。
修复后效果

勾选弹窗内分类时,复选框会实时更新选中状态,同时外层商品列表会立刻根据选中的分类过滤展示对应商品,取消全部分类勾选时自动展示全部商品。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:03:22