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

Flutter Bloc环境下ListView结合TextField搜索无响应问题求助

问题原因及解决方案

你的问题核心是在BlocBuilder中直接覆盖了用于搜索过滤的数据源,且ListView的构建依赖变量被Bloc状态重建时重置:

  • 每次BlocBuilder因组件重建(比如setState触发)执行时,只要当前状态还是CustomerGetAllLoadedState,就会把_customersFromRepo重新赋值为state.customers(全量数据),覆盖了你过滤后的结果。
  • 你只用了一个列表变量同时承担「全量数据源」和「过滤后显示数据」的角色,导致数据逻辑混乱。

修复步骤

1. 拆分数据源变量

在State类中声明两个独立的列表:

// 保存从Bloc获取的全量原始数据,仅在Bloc状态更新时赋值
List<Customer> _allCustomers = [];
// 保存过滤后的数据,用于ListView显示,搜索时更新
List<Customer> _filteredCustomers = [];

2. 修改BlocBuilder逻辑

在BlocBuilder中仅更新全量数据源,并初始化过滤列表,ListView基于_filteredCustomers构建:

BlocBuilder<CustomerBloc, CustomerState>(
  builder: (context, state) {
    if (state is CustomerLoadingState) {
      return const Center(child: CircularProgressIndicator());
    }
    if (state is CustomerGetAllLoadedState) {
      // 仅当全量数据变化时更新,避免每次重建都重置
      if (_allCustomers != state.customers) {
        _allCustomers = state.customers;
        // 初始化过滤列表为全量数据
        _filteredCustomers = List.from(_allCustomers);
      }
      return SizedBox(
        height: h * 0.5,
        width: w * 0.5,
        child: _filteredCustomers.isNotEmpty 
            ? ListView.builder(
                itemCount: _filteredCustomers.length,
                itemBuilder: (context, index) => Card(
                  key: ValueKey(_filteredCustomers[index].id),
                  child: Text(_filteredCustomers[index].name),
                ),
              )
            : const Center(child: Text("无客户数据")),
      );
    }
    // 处理其他状态,比如错误状态
    return const Center(child: Text("加载失败"));
  },
)

3. 调整过滤方法

基于全量数据源_allCustomers进行过滤,更新_filteredCustomers:

void _runFilter(String enteredKeyword) {
  List<Customer> results = [];
  if (enteredKeyword.trim().isEmpty) {
    // 搜索为空时,恢复全量数据
    results = List.from(_allCustomers);
  } else {
    final lowerKeyword = enteredKeyword.toLowerCase();
    results = _allCustomers
        .where((customer) => 
            customer.name.toString().toLowerCase().contains(lowerKeyword))
        .toList();
  }
  setState(() {
    _filteredCustomers = results;
  });
}

关键说明

  • 拆分数据源后,全量数据只在Bloc返回新的全量列表时更新,不会被搜索操作修改,保证过滤的原始数据始终正确。
  • BlocBuilder中加入了_allCustomers != state.customers的判断,避免每次组件重建都重复赋值,提升性能。
  • ListView的构建依赖_filteredCustomers,当搜索触发setState后,组件重建时会使用最新的过滤列表渲染,解决了不更新的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:45:40