如何使用TextField过滤从Firebase获取的ListView并在Flutter上显示匹配的项目?

3b6akqbq  于 2023-03-13  发布在  Flutter
关注(0)|答案(1)|浏览(107)

我想在一个文本字段上进行搜索,它显示在CloudFirestore上进行搜索的结果。这段代码在我打印时提供了结果。我如何在界面上显示它?此外,我应该说,当我尝试方法arrayContains时,为了基于字符串的一部分获得结果,我的打印不起作用,只能打印整个字符串(isEqualTo)。

import 'package:firebase_core/firebase_core.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'Home.dart';

void main ()async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  runApp(MaterialApp(
    home: Home(),

  ));
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  State<Home> createState() => _HomeState();
}
class _HomeState extends State<Home> {
  TextEditingController _controllerField = TextEditingController();

  final CollectionReference _materias =
  FirebaseFirestore.instance.collection('materias');
List searchResult = [];

   searchFF(String query) async{
    final result = await FirebaseFirestore.instance
        .collection('materias')
        .where('unidades_tematicas',
     isEqualTo: query).get();

setState(() {
  searchResult = result.docs.map((x) => x.data()).toList();
  print(searchResult);
});
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("BNCC - Matemática"),
          centerTitle: true,
          backgroundColor: Colors.green,
        ),
        body:
        Column(
            children: [
              TextField(
                controller: _controllerField,
                decoration: InputDecoration(
                  border: OutlineInputBorder(),
                  hintText: "Buscar"
                ),
                onChanged: (query) {
                  searchFF(query);
                },
              ),

              StreamBuilder(
                stream: _materias.snapshots(),
                builder: (context,
                    AsyncSnapshot<QuerySnapshot> streamSnapshot) {
                  if (streamSnapshot.hasData) {

                       return
                          Expanded(child:
                          ListView.builder(
                      scrollDirection: Axis.vertical,
                        shrinkWrap: true,
                        itemCount: streamSnapshot.data!.docs.length,

                        itemBuilder: (context, indice) {
                          DocumentSnapshot documentSnapshot =
                          streamSnapshot.data!.docs[indice];
                          return Column(
                            children: [
                              ListTile(
                                title: Text(
                                    documentSnapshot['unidades_tematicas']),
                                subtitle: Text(documentSnapshot['habilidades']),
                              )
                              ],

                          );
                        }));
                  }
                  return Container(
                  );
                },
              )
            ]
        )
    );
  }
}

界面如下所示:

wgeznvg7

wgeznvg71#

要在UI中显示搜索结果,您需要更改代码以始终使用流。
首先添加一个包含_materias流的字段到小部件的状态,而不仅仅是引用:

class _HomeState extends State<Home> {
  TextEditingController _controllerField = TextEditingController();

  final CollectionReference _materias =
  FirebaseFirestore.instance.collection('materias');
  Stream<QuerySnapshot> _stream = _materias.snapshots()

  ...

  @override
  Widget build(BuildContext context) {
    ...
              StreamBuilder(
                stream: _stream,
  ...

现在,当你实现搜索时,你只需要用过滤后的结果流替换_stream的值就可以了。

searchFF(String query) async {
  const query = await FirebaseFirestore.instance
        .collection('materias')
        .where('unidades_tematicas', isEqualTo: query);
  
  setState(() {
    _stream = query.snapshots();
  });
}

这与Firebase文档中显示实时更新的示例非常相似,因此我建议在更改代码时将其放在手边。

相关问题