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数据效果图:

- 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
相关产品推荐
相关产品推荐

