Flutter多选下拉框问题:如何让最新选中项显示在最前方?
解决multi_dropdown最新选中项显示在横向滚动最前方的问题
修改思路
- 用自定义状态变量维护选中项列表,控制最新选中项排在列表头部
- 自定义选中项的横向滚动视图,通过
ScrollController自动滚动到最左侧 - 在选中/取消选项时同步更新状态和控制器
修改后的完整代码
class MultiDropDown extends StatefulWidget { const MultiDropDown({Key? key}) : super(key: key); @override State<MultiDropDown> createState() => _MultiDropDownState(); } class _MultiDropDownState extends State<MultiDropDown> { final MultiSelectController _controller = MultiSelectController(); final ScrollController _scrollController = ScrollController(); List<ValueItem> _selectedItems = const [ ValueItem(label: 'Option 5', value: '5'), ValueItem(label: 'Option 6', value: '6'), ]; @override void initState() { super.initState(); // 初始化控制器选中状态 _controller.setSelectedOptions(_selectedItems); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Home'), ), body: Column( children: [ MultiSelectDropDown( showClearIcon: true, controller: _controller, onOptionSelected: (options) { setState(() { // 筛选出本次新增的选项(不在原有列表中的) final newSelected = options.where((opt) => !_selectedItems.any((item) => item.value == opt.value) ).toList(); // 筛选出保留的原有选项(仍在选中列表中的) final retainedItems = _selectedItems.where((item) => options.any((opt) => opt.value == item.value) ).toList(); // 新选项放头部,保留项跟在后面 _selectedItems = [...newSelected, ...retainedItems]; }); // 选中后自动滚动到最左侧 WidgetsBinding.instance.addPostFrameCallback((_) { if (_scrollController.hasClients) { _scrollController.animateTo( 0, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } }); }, options: const <ValueItem>[ ValueItem(label: 'Option 1', value: '1'), ValueItem(label: 'Option 2', value: '2'), ValueItem(label: 'Option 3', value: '3'), ValueItem(label: 'Option 4', value: '4'), ValueItem(label: 'Option 5', value: '5'), ValueItem(label: 'Option 6', value: '6'), ], selectionType: SelectionType.multi, chipConfig: const ChipConfig(wrapType: WrapType.scroll), selectedOptions: _selectedItems, selectedItemBuilder: (BuildContext context, List<ValueItem> selectedItems) { return SizedBox( height: 40, child: ListView.builder( controller: _scrollController, scrollDirection: Axis.horizontal, padding: const EdgeInsets.symmetric(horizontal: 8), itemCount: _selectedItems.length, itemBuilder: (ctx, index) { final item = _selectedItems[index]; return Padding( padding: const EdgeInsets.only(right: 8), child: Chip( label: Text(item.label), onDeleted: () { setState(() { _selectedItems.remove(item); _controller.setSelectedOptions(_selectedItems); }); }, ), ); }, ), ); }, dropdownHeight: 300, optionTextStyle: const TextStyle(fontSize: 16), selectedOptionIcon: const Icon(Icons.check_circle), ), ], ), ); } }
关键修改点说明
- 自定义选中项列表:用
_selectedItems替代默认选中项,手动控制顺序,新增项始终插入到列表头部 - 滚动控制:通过
ScrollController在选中后触发滚动动画,自动定位到最左侧 - 同步控制器状态:在取消chip时手动更新
MultiSelectController的选中状态,保证下拉菜单和选中视图状态一致
内容的提问来源于stack exchange,提问作者Shashi Kant
相关产品推荐
相关产品推荐

