Dart:如何在MultiSelectContainer的onChange特定条件下禁用选择?
如何在Dart的MultiSelectContainer组件中按条件禁用点击选择功能
我需要在Dart的MultiSelectContainer组件的onChange回调中实现条件性禁用点击选择的功能。具体需求是:当当前选中项的索引减1等于上一个选中项的索引(即选中顺序符合要求)时,触发禁用点击的逻辑。之前搜索相关内容未找到可行方案,以下是我的代码:
bool scheduleDeselect = true; MultiSelectContainer( controller: controllerMultipleSelect, itemsPadding: const EdgeInsets.all(10), showInListView: true, listViewSettings: ListViewSettings( scrollDirection: Axis.horizontal, separatorBuilder: (_, __) => const SizedBox( width: 10, )), items: List.generate(dataSchedule == null ? 0 : dataSchedule.length, (index) => MultiSelectCard( enabled: scheduleDeselect, value: index.toString() +"-"+ dataSchedule[index]['time_slot'], label: dataSchedule[index]['time_slot'], )), onChange: (allSelectedItems, selectedItem) { if(allSelectedItems.length>1) { var lst = allSelectedItems[allSelectedItems.length - 2]; debugPrint("lasted:$lst"); var pos = lst.toString().lastIndexOf('-'); String previousResult = (pos != -1)? lst.substring(0, pos): lst; var pos1 = selectedItem.toString().lastIndexOf('-'); String currResult = (pos1 != -1)? selectedItem.substring(0, pos1): selectedItem; if(int.parse(currResult)-1 == int.parse(previousResult)){ // 我想在这里应用禁用点击的逻辑 debugPrint("Correct order"); }else{ scheduleDeselect = false; debugPrint("Incorrect order"); } } })
解决方案
你当前用全局变量scheduleDeselect控制所有MultiSelectCard的启用状态,会导致所有选项同时被禁用/启用,无法实现按需控制的效果。可以通过以下方式修改:
- 改用列表单独记录每个选项的启用状态,避免全局变量的影响
- 在满足条件时通过
setState更新状态,动态控制选项的可点击性
修改后的代码示例:
// 初始化列表,记录每个选项的启用状态 List<bool> itemEnabledList = []; @override void initState() { super.initState(); // 初始时所有选项都可点击 itemEnabledList = List.generate(dataSchedule?.length ?? 0, (_) => true); } // ... 其他代码 MultiSelectContainer( controller: controllerMultipleSelect, itemsPadding: const EdgeInsets.all(10), showInListView: true, listViewSettings: ListViewSettings( scrollDirection: Axis.horizontal, separatorBuilder: (_, __) => const SizedBox(width: 10), ), items: List.generate(dataSchedule?.length ?? 0, (index) => MultiSelectCard( enabled: itemEnabledList[index], // 单独控制每个选项的启用状态 value: "${index}-${dataSchedule[index]['time_slot']}", label: dataSchedule[index]['time_slot'], )), onChange: (allSelectedItems, selectedItem) { if (allSelectedItems.length > 1) { var lst = allSelectedItems[allSelectedItems.length - 2]; debugPrint("lasted:$lst"); var pos = lst.toString().lastIndexOf('-'); String previousResult = (pos != -1) ? lst.substring(0, pos) : lst; var pos1 = selectedItem.toString().lastIndexOf('-'); String currResult = (pos1 != -1) ? selectedItem.substring(0, pos1) : selectedItem; if (int.parse(currResult) - 1 == int.parse(previousResult)) { debugPrint("Correct order"); // 满足顺序要求时,禁用所有未选中的选项 setState(() { for (int i = 0; i < itemEnabledList.length; i++) { // 判断当前索引的选项是否已被选中 bool isSelected = allSelectedItems.any((item) { var itemPos = item.toString().lastIndexOf('-'); String itemIndex = (itemPos != -1) ? item.toString().substring(0, itemPos) : item.toString(); return itemIndex == i.toString(); }); // 只保留已选中的选项可点击,其余禁用 itemEnabledList[i] = isSelected; } }); } else { debugPrint("Incorrect order"); // 顺序不符合时,禁用当前选中项并移除它 setState(() { int currIndex = int.parse(currResult); itemEnabledList[currIndex] = false; controllerMultipleSelect.removeItem(selectedItem); }); } } }, )
说明
- 用
itemEnabledList替代全局变量,实现对单个选项的启用状态控制 - 当选中顺序符合要求时,通过
setState更新列表,禁用未选中的选项,达到无法继续点击选择的效果 - 顺序不符合时,可选择禁用当前项并通过控制器移除,也可根据实际需求调整逻辑
内容的提问来源于stack exchange,提问作者YourDeveloper
相关产品推荐
相关产品推荐

