Flutter中为复选框添加搜索筛选功能的问题求助
Flutter 复选框搜索筛选功能修复方案
问题诊断
你的代码存在三个核心问题导致不符合预期:
- 全局变量误用:
selectedEmployees和employees被定义为全局变量,多次打开弹窗会导致状态残留,且未使用Widget传入的widget.employees作为数据源 - 渲染数据源错误:ListBody始终渲染
widget.employees的全部选项,未关联筛选后的_foundUsers列表,导致搜索后所有选项仍显示 - 初始数据绑定错误:
initState中初始化_foundUsers时用了全局的employees,而非传入的widget.employees
修复后的完整代码
multi_select.dart
import "package:flutter/material.dart"; import "package:get/get.dart"; import "package:tact_tik/fonts/inter_light.dart"; import "package:tact_tik/fonts/inter_medium.dart"; import "package:tact_tik/utils/colors.dart"; class MultiSelect extends StatefulWidget { final List<String> employees; const MultiSelect({super.key, required this.employees}); @override State<MultiSelect> createState() => _MultiSelectState(); } class _MultiSelectState extends State<MultiSelect> { // 将选中列表移到State内部,避免全局状态污染 List<String> selectedEmployees = []; List<String> _foundUsers = []; @override void initState() { // 使用传入的数据源初始化筛选列表 _foundUsers = widget.employees; super.initState(); } void _itemChange(String employeeValue, bool isSelected) { setState(() { if (isSelected) { selectedEmployees.add(employeeValue); } else { selectedEmployees.remove(employeeValue); } }); } void _runFilter(String enteredKey) { List<String> results = []; if (enteredKey.isEmpty) { // 搜索为空时显示全部选项 results = widget.employees; } else { // 基于传入的数据源进行大小写不敏感的筛选 results = widget.employees .where((employee) => employee.toLowerCase().contains(enteredKey.toLowerCase())) .toList(); } setState(() { _foundUsers = results; }); } void _cancel() { Navigator.pop(context); } void _submit() { Navigator.pop(context, selectedEmployees); print(selectedEmployees); } @override Widget build(BuildContext context) { final bool isDark = Theme.of(context).brightness == Brightness.dark; return AlertDialog( scrollable: true, title: InterMedium( text: "Select Employees", color: isDark ? DarkColor.Primarycolor : LightColor.Primarycolor, ), content: SingleChildScrollView( child: Column( children: [ TextField( onChanged: (value) => _runFilter(value), decoration: InputDecoration( labelText: 'Search Employee', suffixIcon: Icon(Icons.search)), ), ListBody( // 改为渲染筛选后的列表_foundUsers children: _foundUsers .map((item) => CheckboxListTile( activeColor: isDark ? DarkColor.Primarycolor : LightColor.Primarycolor, value: selectedEmployees.contains(item), title: InterLight( text: item, ), controlAffinity: ListTileControlAffinity.leading, onChanged: (isChecked) => _itemChange(item, isChecked!), )) .toList(), ), ], ), ), actions: [ TextButton( onPressed: _cancel, child: InterMedium( text: 'Cancel', color: isDark ? DarkColor.color2 : LightColor.color4, ), ), ElevatedButton( onPressed: _submit, child: InterMedium( text: "Submit", color: isDark ? DarkColor.Primarycolor : LightColor.Primarycolor), ) ], ); } }
修复说明
- 状态本地化:将
selectedEmployees移到State内部,确保每次打开弹窗都是全新的选择状态 - 数据源统一:所有数据操作都基于Widget传入的
widget.employees,避免全局数据不一致 - 渲染关联筛选结果:ListBody的数据源改为
_foundUsers,实现搜索时仅显示匹配的复选框选项 - 筛选逻辑优化:保持大小写不敏感的搜索逻辑,同时确保空搜索时显示全部选项
内容的提问来源于stack exchange,提问作者Tahmeed Zamindar
相关产品推荐
相关产品推荐

