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

在ListView Builder中集成Firestore字段搜索功能

在ListView Builder中集成搜索过滤功能

要实现只显示搜索匹配的文档,同时保留ListView Builder的索引功能,核心是维护一个过滤后的文档列表,而非直接使用快照中的全部数据。以下是具体实现方案:

核心逻辑

  • 用状态变量存储搜索关键词和过滤后的文档集合
  • 监听搜索框输入变化,实时筛选出匹配nom_categorie字段的文档
  • ListView.builder基于过滤后的列表构建UI,确保只展示匹配结果,同时正常使用索引

修改后的完整代码示例

假设你使用StatefulWidget(若用GetX可替换为响应式变量逻辑):

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart';
import 'package:cloud_firestore/cloud_firestore.dart'; // 引入Firebase依赖

class CategoryScreen extends StatefulWidget {
  const CategoryScreen({super.key});

  @override
  State<CategoryScreen> createState() => _CategoryScreenState();
}

class _CategoryScreenState extends State<CategoryScreen> {
  final TextEditingController _searchController = TextEditingController();
  List<DocumentSnapshot> _filteredDocs = [];

  @override
  void initState() {
    super.initState();
    // 监听搜索输入,实时触发过滤
    _searchController.addListener(_filterDocuments);
  }

  @override
  void dispose() {
    _searchController.dispose();
    super.dispose();
  }

  // 过滤逻辑:匹配分类名称,不区分大小写
  void _filterDocuments() {
    final query = _searchController.text.toLowerCase();
    // 这里替换为你获取原始快照数据的方式,比如从父组件传入或直接查询
    FirebaseFirestore.instance.collection("你的集合名").get().then((snapshot) {
      setState(() {
        _filteredDocs = snapshot.docs.where((doc) {
          final data = doc.data() as Map<String, dynamic>;
          final categoryName = data["nom_categorie"].toLowerCase();
          return categoryName.contains(query);
        }).toList();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 添加搜索栏
      appBar: AppBar(
        title: TextField(
          controller: _searchController,
          decoration: const InputDecoration(
            hintText: "搜索分类...",
            border: InputBorder.none,
            hintStyle: TextStyle(color: Colors.white70),
          ),
          style: const TextStyle(color: Colors.white),
        ),
      ),
      body: FutureBuilder<QuerySnapshot>(
        future: FirebaseFirestore.instance.collection("你的集合名").get(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return const Center(child: CircularProgressIndicator());
          }
          // 初始化过滤列表为全部文档
          if (_filteredDocs.isEmpty) {
            _filteredDocs = snapshot.data!.docs;
          }

          return ListView.builder(
            itemCount: _filteredDocs.length, // 使用过滤后的列表长度
            itemBuilder: (context, index) {
              var doc = _filteredDocs[index]; // 从过滤列表取目标文档
              var data = doc.data() as Map<String, dynamic>;
              return Column(
                children: [
                  SizedBox(
                    height: MediaQuery.of(context).size.height * 0.0237,
                  ),
                  FadeIn(
                    child: GestureDetector(
                      onTap: () {
                        Get.toNamed("Route", arguments: RecupDataDocuments(docID: doc.id.toString()));
                      },
                      child: Container(
                        height: MediaQuery.of(context).size.height * 0.102,
                        width: double.maxFinite,
                        padding: EdgeInsets.symmetric(
                          horizontal: MediaQuery.of(context).size.width * 0.096
                        ),
                        decoration: BoxDecoration(
                          color: Theme.of(context).shadowColor,
                          borderRadius: BorderRadius.circular(MediaQuery.of(context).devicePixelRatio / 0.16),
                          boxShadow: [
                            BoxShadow(
                              offset: Offset(
                                0,
                                MediaQuery.of(context).size.height * 0.006
                              ),
                              color: Colors.black.withOpacity(0.15),
                              blurRadius: 4,
                              blurStyle: BlurStyle.normal
                            ),
                          ]
                        ),
                        child: Row(
                          mainAxisAlignment: MainAxisAlignment.spaceBetween,
                          children: [
                            Text(
                              data["nom_categorie"],
                              style: TextStyle(
                                fontSize: MediaQuery.of(context).size.height * 0.0237,
                                color: Theme.of(context).primaryColor
                              ),
                            ),
                            Icon(
                              FontAwesomeIcons.chevronRight,
                              color: Theme.of(context).primaryColor,
                              size: MediaQuery.of(context).size.height * 0.026
                            )
                          ],
                        ),
                      ),
                    ),
                  )
                ],
              );
            },
          );
        },
      ),
    );
  }
}

// 保留你原有的RecupDataDocuments类
class RecupDataDocuments {
  final String docID;
  RecupDataDocuments({required this.docID});
}

关键修改说明

  • 新增搜索控制器监听输入,实时执行过滤逻辑
  • 用_filteredDocs存储匹配结果,ListView.builder完全基于这个列表渲染
  • 过滤时统一转为小写,实现不区分大小写的搜索体验
  • 初始化时将过滤列表设为全部文档,保证默认显示完整数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 05:05:16