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

Flutter中为复选框添加搜索筛选功能的问题求助

Flutter 复选框搜索筛选功能修复方案

问题诊断

你的代码存在三个核心问题导致不符合预期:

  1. 全局变量误用:selectedEmployees和employees被定义为全局变量,多次打开弹窗会导致状态残留,且未使用Widget传入的widget.employees作为数据源
  2. 渲染数据源错误:ListBody始终渲染widget.employees的全部选项,未关联筛选后的_foundUsers列表,导致搜索后所有选项仍显示
  3. 初始数据绑定错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:14:53