在 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]);
},
),
),
],
);
}
}
嘿,我试过同样的东西,但我得到一个空白屏幕,如果可能的话,请分享源代码。
编辑:我知道我错在哪里了。非常感谢您提供的解决方案,这真的很有帮助
我正在尝试在我的应用程序中实现搜索功能。现在我有一个 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]);
},
),
),
],
);
}
}
嘿,我试过同样的东西,但我得到一个空白屏幕,如果可能的话,请分享源代码。
编辑:我知道我错在哪里了。非常感谢您提供的解决方案,这真的很有帮助