在 Flutter 的 ListView 中搜索(使用来自 Firebase 的数据)

Search in ListView (with Data from Firebase) in Flutter

我正在尝试在我的应用程序中实现搜索功能。现在我有一个 ListView,它将我从 Firebase 数据库中获取的数据显示为流。您对如何搜索此列表有任何想法吗?

这是我的 ListView 代码:

import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";

class ImbissList extends StatefulWidget {
  @override
  _ImbissListState createState() => _ImbissListState();
}

class _ImbissListState extends State<ImbissList> {

  @override
  Widget build(BuildContext context) {
    final imbiss = Provider.of<List<Imbiss>>(context);


    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: TextField(
            decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
            style: TextStyle(color: Colors.white),
          ),
        ),
        SizedBox(height: 10,),
        Expanded(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: imbiss.length ?? 0,
            itemBuilder: (context, index){
              return ImbissTile(imbiss: imbiss[index]);
            },
          ),
        ),
      ],
    );
  }
}

下面是我在应用程序的主屏幕中实现 ListView 的方式:

import 'package:rate_my_food_1/models/imbiss.dart';
import "package:rate_my_food_1/services/database.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_list.dart";




class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {



  @override
  Widget build(BuildContext context) {

    return StreamProvider<List<Imbiss>>.value(
        value: DatabaseService().imbisses,
        child: Scaffold(
          backgroundColor: Colors.grey[800],
          //Add Button
          floatingActionButton: FloatingActionButton(
            onPressed: (){
              Navigator.pushNamed(context, "/add");
            },
            child: Icon (Icons.add),
            backgroundColor: Colors.cyanAccent,
          ),
          body: Column(
            children: <Widget>[
              SafeArea(child: SizedBox(height: 10.0,)),
              //Imbissliste
              Expanded(child: ImbissList()),
            ],
          )
        )
    );
  }
}

我正在考虑制作第二个列表,在其中我只能过滤包含我正在写入 TextField 的内容的对象,但我不知道如何正确地做到这一点。 您对如何在此 ListView 中进行搜索有任何想法吗?

如果您需要我项目中的更多代码,请告诉我。 感谢您的所有回答! 约克拉

编辑: 这是我的 Code atm,问题是当我启动应用程序时它不显示 ListView 和 TextField:

import "package:rate_my_food_1/models/imbiss.dart";
import "package:provider/provider.dart";
import "package:rate_my_food_1/widgets/imbiss_tile.dart";

class ImbissList extends StatefulWidget {
  @override
  _ImbissListState createState() => _ImbissListState();
}

class _ImbissListState extends State<ImbissList> {

  List<Imbiss> imbiss = [];
  List<Imbiss> filteredImbiss = [];

  @override
  initState() {
    imbiss = Provider.of<List<Imbiss>>(context);
    filteredImbiss = imbiss;

    super.initState();
  }

  @override
  Widget build(BuildContext context) {

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: TextField(
            decoration: InputDecoration(hintText: "Suchen...", hintStyle: TextStyle(color: Colors.white)),
            style: TextStyle(color: Colors.white),
            onChanged: (value) {
              setState(() {
               filteredImbiss = imbiss.where((imbiss) => imbiss.name.contains(value)).toList();
             });
            },
          ),
        ),
        SizedBox(height: 10,),
        Expanded(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: filteredImbiss.length,
            itemBuilder: (context, index){
              return ImbissTile(imbiss: filteredImbiss[index]);
            },
          ),
        ),
      ],
    );
  }
}`

我们可以使用状态键过滤检索到的数据。此密钥可以使用 TextField 小部件中的 onChanged(String) 方法进行更新。我们只是在每次构建时过滤列表,请看下面的例子:

class ImbissList extends StatefulWidget {
  @override
  _ImbissListState createState() => _ImbissListState();
}

class _ImbissListState extends State<ImbissList> {
  // The search key to filter the imbisses.
  String key = '';

  @override
  Widget build(BuildContext context) {
    var imbisses = Provider.of<List<Imbiss>>(context);

    // Filter the imbisses using the key.
    imbisses = imbisses.where((imbiss) {
      return imbiss.name.contains(key);
    }).toList();

    return Column(
      children: [
        Padding(
          padding: const EdgeInsets.all(8.0),
          child: TextField(
            decoration: InputDecoration(
              hintText: "Suchen...",
              hintStyle: TextStyle(color: Colors.white)),
            style: TextStyle(color: Colors.white),
            onChanged: (value) {
              // Update the key when the value changes.
              setState(() => key = value);
            },
          ),
        ),
        SizedBox(
          height: 10,
        ),
        Expanded(
          child: ListView.builder(
            shrinkWrap: true,
            itemCount: imbisses.length,
            itemBuilder: (context, index) {
              return ImbissTile(imbiss: imbisses[index]);
            },
          ),
        ),
      ],
    );
  }
}

嘿,我试过同样的东西,但我得到一个空白屏幕,如果可能的话,请分享源代码。

编辑:我知道我错在哪里了。非常感谢您提供的解决方案,这真的很有帮助