在 Flutter 中的 ListView 中搜索(使用 Firebase 中的数据)
Posted
技术标签:
【中文标题】在 Flutter 中的 ListView 中搜索(使用 Firebase 中的数据)【英文标题】:Search in ListView (with Data from Firebase) in Flutter 【发布时间】:2021-07-24 13:07:38 【问题描述】:我正在尝试在我的应用中实现搜索功能。现在我有一个 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 中进行搜索有任何想法吗?
如果您需要我的项目中的更多代码,请告诉我。 感谢所有答案! 优酷
编辑: 这是我的代码 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]);
,
),
),
],
);
`
【问题讨论】:
嘿!您只想过滤已加载的列表吗?还是要动态查询firestore? 动态查询 Firestore 听起来很理想,但我对这两种解决方案都很满意! 【参考方案1】:我们可以使用 state 中的键过滤检索到的数据。可以使用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]);
,
),
),
],
);
【讨论】:
您好,非常感谢您的快速答复。但是由于某种原因,当我现在启动应用程序时,我得到的只是一个灰屏。它也没有显示 TextField .. 唯一存在的是 floatingActionButton。你知道为什么会这样吗? 嗯,这很奇怪。当我尝试实现上面的小部件时,它工作得很好。 Flutter 会抛出任何错误吗? 我没有收到任何错误。经过反复试验,我发现当我不是在 InitState 中而是直接在 Build Widget 中使用“imbiss = Provider.of>(context);filteredImbiss = imbiss;”初始化列表时它像以前一样工作并向我显示列表和文本字段,但是当我输入内容时没有任何反应.. 没错。这样,列表将在每次构建时初始化(因此当 textField 更新时),因此不会发生任何变化。也许唯一的选择是将Imbisses
作为参数传递给ImbissList
小部件?
你能告诉我怎么做吗? (如果你有时间)【参考方案2】:
嘿,我尝试了同样的事情,但我得到一个空白屏幕,如果可以的话,请你分享源代码。
编辑:我知道我哪里出错了。非常感谢您提供的解决方案,这真的很有帮助
【讨论】:
以上是关于在 Flutter 中的 ListView 中搜索(使用 Firebase 中的数据)的主要内容,如果未能解决你的问题,请参考以下文章
Flutter 动画列表:有条件地添加 ListView 项
Flutter - 另一个 Listview 中的 Listview.builder
在 Flutter 应用程序的 ListView.builder 中添加滚动
在 Flutter 应用程序中的 ListView 滚动上隐藏/关闭键盘