Flutter -如何在列表中搜索并在ListView中显示?

wgx48brx  于 2023-02-20  发布在  Flutter
关注(0)|答案(1)|浏览(139)

我正在为我开发的Flutter应用程序编写一个搜索系统。我在后端遇到了一个问题。首先我从Firebase Firestore中提取数据。然后我将其转换为模型结构。
检索系统代码:

StreamBuilder(
    stream: db.collection("DebrisPeoples").snapshots(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        return const Center(
          child: CircularProgressIndicator(),
        );
      } else {
        final List<DebrisPeopleModel> data = snapshot.data!.docs
            .map((e) => DebrisPeopleModel.fromDocument(e))
            .toList(); // To Model code
        return Column(
          children: [
            const SizedBox(height: 10),
            SizedBox(
              width: MediaQuery.of(context).size.width * 0.95,
              child: TextFormField(
                decoration: InputDecoration(
                  prefixIcon: const Icon(Icons.search),
                  contentPadding: const EdgeInsets.only(),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(30),
                  ),
                ),
                onChanged: (value) {
                  final find = data.where(
                      (element) => data.contains(element.nameSurname));
                  print(find); // PROBLEM - NOT WORKING
                },
              ),
            ),
            SizedBox(
              width: double.infinity,
              height: MediaQuery.of(context).size.height * 0.8,
              child: ListView.builder(
                physics: const BouncingScrollPhysics(),
                itemCount: data.length,
                itemBuilder: (context, index) {
                  return Card(
                    child: ListTile(
                      leading: Icon(
                        data[index].personSize == 1
                            ? Icons.person
                            : Icons.people,
                      ),
                      title: Text(data[index].nameSurname.toString()),
                      subtitle: Text(
                        "${data[index].city} / ${data[index].district}",
                      ),
                      trailing: IconButton(
                        icon: const Icon(Icons.info),
                        onPressed: () {
                          Get.to(const UnderRublePeopleDetailPage(),
                              arguments: data[index]);
                          print(data[index].nameSurname);
                        },
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        );
      }
    },
  ),

我的目标是,例如,如果存在ABC的记录,我希望即使用户搜索AAB,它也会出现在结果中。
然后我希望结果显示在列表中。我将感谢您的帮助:)
要更改搜索结果:

final find = data.where((element) => element
      .nameSurname!
      .toLowerCase()
      .contains(value.toLowerCase()));
  print(find);
  setState(() {
    data = find.toList();
    print(data);
  });

我试着做这样一个搜索系统。但是,当我输入TextFormField时,ListView中的结果不会改变。

cotxawn7

cotxawn71#

您的onChanged代码应该如下所示。

onChanged: (value) {
                  final find = data.where(
                      (element) => element.nameSurname.toLowerCase().contains(value.toLowerCase()));
                  print(find);
                }

确保您正在管理状态以反映UI上的更改。

已编辑

final controller = TextEditingController();//Keep this as a field

  StreamBuilder(
    stream: db.collection("DebrisPeoples").snapshots(),
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        return const Center(
          child: CircularProgressIndicator(),
        );
      } else {
        final searchText = controller.text.trim().toLowerCase();
        final List<DebrisPeopleModel> data = snapshot.data!.docs
            .map((e) => DebrisPeopleModel.fromDocument(e))
            .where((e) => searchText.isEmpty || e.nameSurname!
            .toLowerCase().contains(searchText))
            .toList(); // To Model code
        return Column(
          children: [
            const SizedBox(height: 10),
            SizedBox(
              width: MediaQuery
                  .of(context)
                  .size
                  .width * 0.95,
              child: TextFormField(
                controller: controller,
                decoration: InputDecoration(
                  prefixIcon: const Icon(Icons.search),
                  contentPadding: const EdgeInsets.only(),
                  border: OutlineInputBorder(
                    borderRadius: BorderRadius.circular(30),
                  ),
                ),
                onChanged: (value) {
                  setState((){ });
                },
              ),
            ),
            SizedBox(
              width: double.infinity,
              height: MediaQuery
                  .of(context)
                  .size
                  .height * 0.8,
              child: ListView.builder(
                physics: const BouncingScrollPhysics(),
                itemCount: data.length,
                itemBuilder: (context, index) {
                  return Card(
                    child: ListTile(
                      leading: Icon(
                        data[index].personSize == 1
                            ? Icons.person
                            : Icons.people,
                      ),
                      title: Text(data[index].nameSurname.toString()),
                      subtitle: Text(
                        "${data[index].city} / ${data[index].district}",
                      ),
                      trailing: IconButton(
                        icon: const Icon(Icons.info),
                        onPressed: () {
                          Get.to(const UnderRublePeopleDetailPage(),
                              arguments: data[index]);
                          print(data[index].nameSurname);
                        },
                      ),
                    ),
                  );
                },
              ),
            ),
          ],
        );
      }
    },
  )

相关问题