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

Flutter多选下拉框问题:如何让最新选中项显示在最前方?

解决multi_dropdown最新选中项显示在横向滚动最前方的问题

修改思路

  1. 用自定义状态变量维护选中项列表,控制最新选中项排在列表头部
  2. 自定义选中项的横向滚动视图,通过ScrollController自动滚动到最左侧
  3. 在选中/取消选项时同步更新状态和控制器

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 10:40:23