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

Flutter酒水配送应用嵌套列表搜索无结果问题求助

解决Flutter酒水分类嵌套列表搜索与渲染列表不一致的问题

核心方案:维护双列表状态,统一渲染数据源

解决的关键是让搜索逻辑和UI渲染完全共用同一套过滤后的列表,同时保留原始全量数据用于重置搜索。


步骤1:定义状态变量

在你的State类(或状态管理类)中声明两个列表:

  • 一个存储原始全部分类数据(仅初始化时赋值,后续不修改)
  • 一个存储过滤后的数据(搜索时更新,UI始终渲染这个列表)

示例代码:

// 假设你的分类与酒水模型结构
class Category {
  final String name;
  final List<Drink> drinks;
  Category({required this.name, required this.drinks});
}

class Drink {
  final String name;
  Drink({required this.name});
}

// State类中的状态变量
List<Category> _originalCategories = [];
List<Category> _filteredCategories = [];

// 初始化时加载全量数据并同步给过滤列表
@override
void initState() {
  super.initState();
  // 替换为你的实际数据加载逻辑(API/本地缓存等)
  _originalCategories = _loadFullCategoryData();
  _filteredCategories = List.from(_originalCategories);
}

步骤2:实现嵌套搜索过滤逻辑

在搜索框的onChanged回调中,基于原始列表生成过滤结果,更新过滤列表并触发UI刷新:

void _onSearchInputChanged(String query) {
  if (query.trim().isEmpty) {
    // 清空搜索时恢复全量数据
    setState(() {
      _filteredCategories = List.from(_originalCategories);
    });
    return;
  }

  // 嵌套过滤:先匹配分类下的酒水,再保留有匹配项的分类
  final filteredResult = _originalCategories.map((category) {
    final matchedDrinks = category.drinks.where((drink) =>
        drink.name.toLowerCase().contains(query.toLowerCase())).toList();
    
    // 仅保留包含匹配酒水的分类
    if (matchedDrinks.isNotEmpty) {
      return Category(
        name: category.name,
        drinks: matchedDrinks,
      );
    }
    return null;
  }).whereType<Category>().toList();

  setState(() {
    _filteredCategories = filteredResult;
  });
}

步骤3:UI渲染完全依赖过滤后的列表

所有嵌套列表的渲染逻辑,都基于_filteredCategories构建,确保搜索结果与渲染内容完全一致:

@override
Widget build(BuildContext context) {
  return Scaffold(
    appBar: AppBar(
      title: TextField(
        onChanged: _onSearchInputChanged,
        decoration: const InputDecoration(
          hintText: "搜索酒水...",
          border: InputBorder.none,
        ),
      ),
    ),
    body: ListView.builder(
      itemCount: _filteredCategories.length,
      itemBuilder: (context, index) {
        final category = _filteredCategories[index];
        return ExpansionTile(
          title: Text(category.name),
          children: category.drinks.map((drink) {
            return ListTile(title: Text(drink.name));
          }).toList(),
        );
      },
    ),
  );
}

避坑提示

  • 禁止直接修改_originalCategories,否则搜索清空后无法恢复全量数据
  • 过滤时统一转换为小写(或大写),避免大小写不匹配导致搜索无结果
  • 嵌套过滤后剔除无匹配酒水的空分类,避免UI出现无效占位项

内容的提问来源于stack exchange,提问作者Anesu Mazvimavi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 12:48:19