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

Flutter中基于Riverpod的FutureProvider如何实现列表搜索过滤

Riverpod + Hooks 实现列表搜索过滤方案

核心逻辑不需要修改你已有的caseEntriesFutureProvider,远程数据拉取逻辑完全保留,搜索过滤作为客户端侧的轻量状态单独处理,和现有.when写法完全兼容。

实现步骤

  • 用useState维护本地搜索关键词状态,不需要新增全局Provider
  • 给已有的文本编辑控制器加监听,输入变化时同步更新关键词状态
  • 当FutureProvider返回全量列表数据后,先根据关键词做匹配过滤,再把过滤后的列表传给网格组件渲染
  • 搜索关键词为空时默认展示全量数据,匹配逻辑默认做大小写不敏感处理,可根据自己的业务字段调整匹配规则

完整实现代码

@override
Widget build(BuildContext context, WidgetRef ref) {
  final caseEntries = ref.watch(caseEntriesFutureProvider);
  final searchTextController = useTextEditingController(text: "");
  // 新增:本地维护搜索关键词状态
  final searchKeyword = useState('');

  useEffect(() {
    void listener() {
      // 输入变化时同步更新关键词
      searchKeyword.value = searchTextController.text;
    }
    searchTextController.addListener(listener);
    // 组件销毁时移除监听
    return () => searchTextController.removeListener(listener);
  }, [searchTextController]);

  return Column(
    children: [
      // 搜索输入框
      Padding(
        padding: const EdgeInsets.all(16.0),
        child: TextField(
          controller: searchTextController,
          decoration: const InputDecoration(
            hintText: "输入关键词搜索",
            prefixIcon: Icon(Icons.search),
            border: OutlineInputBorder(),
          ),
        ),
      ),
      // 原有列表逻辑
      Expanded(
        child: caseEntries.when(
          data: (items) {
            // 核心:根据关键词过滤全量数据
            final filteredItems = items.where((item) {
              final keyword = searchKeyword.value.trim().toLowerCase();
              // 空关键词返回全部数据
              if (keyword.isEmpty) return true;
              // 替换成你实际需要匹配的字段,比如案例名称、编号、描述等
              // 示例为匹配item的title字段
              return item.title.toLowerCase().contains(keyword);
            }).toList();

            // 过滤后无结果的可选提示
            if (filteredItems.isEmpty) {
              return const Center(child: Text("未找到匹配的内容"));
            }

            return GridView.builder(
              gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
                  maxCrossAxisExtent: 380.0),
              scrollDirection: Axis.vertical,
              shrinkWrap: true,
              itemCount: filteredItems.length,
              itemBuilder: (BuildContext context, int index) {
                final item = filteredItems[index];
                return CaseItem(item: item);
              },
            );
          },
          error: (obj, error) => Text(error.toString()),
          loading: () => const material.CircularProgressIndicator(),
        ),
      ),
    ],
  );
}

注意点

  • 如果你需要搜索逻辑走后端接口,只需要把caseEntriesFutureProvider改成接收关键词参数的Family形式,监听关键词变化重新触发请求即可,当前客户端过滤方案适合数据量不大的场景
  • 过滤逻辑里的匹配字段可以根据业务需求扩展,比如同时匹配标题、描述多个字段,只要在where判断里加或条件即可
  • 用useEffect返回的清理函数移除控制器监听,避免内存泄漏

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 23:51:21