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

Flutter中SearchAnchor的SuggestionBuilder不随RiverPod Provider更新

问题修复方案

核心问题分析

  1. 旧数据提前显示:用户输入时,API请求还未完成,suggestionBuilder直接使用了上次的searchResults旧数据。
  2. 建议列表不刷新:SearchAnchor没有监听plannerState的状态变化,即使notifyListeners()触发,suggestionBuilder也不会重新执行。

具体修复步骤

1. 搜索前清空旧数据,避免显示历史结果

修改_searchStations方法,在发起API请求前先清空searchResults并通知状态更新,这样用户输入时会先看到空列表,而非旧数据:

Future<void> _searchStations(String query) async {
  // 搜索开始前清空旧数据,立即通知UI更新
  searchResults = [];
  notifyListeners();

  print("searching $query");
  try {
    searchResults = await StationService().findStation(query);
  } catch (e) {
    // 处理API请求错误,兜底空列表
    searchResults = [];
  }
  print("found ${searchResults.length}");
  notifyListeners();
}

2. 让SearchAnchor监听状态变化

当前stationSearchBar没有监听plannerState的更新,需要用RiverPod的Consumer包裹,确保状态变化时SearchAnchor会重建,suggestionBuilder能获取最新的searchResults:

Widget stationSearchBar(BuildContext context) {
  return Consumer<PlannerViewModel>(
    builder: (context, plannerState, child) {
      // 避免重复添加Listener,只在首次构建时添加
      WidgetsBinding.instance.addPostFrameCallback((_) {
        if (!plannerState.searchController.hasListeners) {
          plannerState.searchController.addListener(() {
            plannerState.searchInputChanged(plannerState.searchController.text);
          });
        }
      });

      return SearchAnchor(
        isFullScreen: false,
        searchController: plannerState.searchController,
        builder: (BuildContext context, SearchController controller) {
          return SearchBar(
            textCapitalization: TextCapitalization.none,
            controller: plannerState.searchController,
            onTap: () => controller.openView(),
          );
        },
        suggestionsBuilder: (BuildContext context, SearchController controller) {
          return plannerState.searchResults.map((Station result) {
            return ListTile(
              title: Text(result.names.values.first),
            );
          }).toList();
        },
      );
    },
  );
}

3. 增加防抖逻辑,减少无效API请求

用户输入过程中会频繁触发searchInputChanged,建议添加防抖,避免每输入一个字符就发起请求:
在PlannerViewModel中添加防抖工具类和修改触发逻辑:

// 简单的防抖工具类
class Debounce {
  final int milliseconds;
  Timer? _timer;

  Debounce({required this.milliseconds});

  void run(VoidCallback action) {
    _timer?.cancel();
    _timer = Timer(Duration(milliseconds: milliseconds), action);
  }
}

// 在ViewModel中初始化防抖
final _debounce = Debounce(milliseconds: 300);

void searchInputChanged(String query) {
  if (query.trim().isEmpty) {
    searchResults = [];
    notifyListeners();
    return;
  }
  // 延迟300ms执行搜索,避免频繁请求
  _debounce.run(() {
    _searchStations(query);
  });
}

修复原理

  • 清空旧数据:确保搜索发起时UI先显示空状态,避免混淆用户。
  • Consumer监听:让SearchAnchor能感知plannerState的状态更新,自动重建并刷新建议列表。
  • 防抖:减少不必要的API请求,优化性能和后端压力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 01:22:12