flutter - 如何在我的 ListView 中搜索特定元素?
问题描述
我有一个 listView,它表示为 gridView。我添加了一个带有 TextController 的搜索栏。Grid 视图具有单独的元素,其中包含名称和年龄。我希望搜索查询搜索名称并仅显示相关元素。
List<Map> itemList = [
{
'Name':"Bob",
'Age':"24"
}
{
'Name':"Billy",
'Age':"34"
}
]
这是我的 GridView 的表示:
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.only(top: 8),
child: FutureBuilder<bool>(
future: getData(),
builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
} else {
return GridView.count(
mainAxisSpacing: 32.0,
crossAxisSpacing: 32.0,
childAspectRatio: 0.8,
shrinkWrap: true,
physics: ClampingScrollPhysics(),
padding: const EdgeInsets.all(8),
crossAxisCount: 2,
children: List<Widget>.generate(
itemList.length,
(int index) {
return GestureDetector(
onTap: () => _goToItemViewer(itemList[index]),
child: CategoryView(
callback: () {
},
item: itemList[index],
),
);
},
),
);
}
},
),
);
}
}
class CategoryView extends StatefulWidget {
final Map item;
const CategoryView({Key key, this.callback, this.item}) : super(key: key);
final VoidCallback callback;
@override
CategoryViewState createState() => CategoryViewState();
}
class CategoryViewState extends State<CategoryView> {
@override
Widget build(BuildContext context) {
return Container(
child: InkWell(
splashColor: Colors.transparent,
child: SizedBox(
height: 280,
child: Stack(
alignment: AlignmentDirectional.bottomCenter,
children: <Widget>[
Container(
child: Container(
child: Column(
children: <Widget>[
Expanded(
child: Container(
decoration: BoxDecoration(
color: Color(0xfff8fafb),
borderRadius:
const BorderRadius.all(Radius.circular(16.0)),
),
child: Column(
children: <Widget>[
Expanded(
child: Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(
top: 16, left: 16, right: 16),
child: Text(
widget.item['Name'],
textAlign: TextAlign.left,
style: TextStyle(
fontWeight: FontWeight.w600,
fontFamily: "Netflix",
fontSize: 16,
letterSpacing: 0.27,
color:
Color(0xFF17262A),
),
),
),
Padding(
padding: const EdgeInsets.only(
top: 8,
left: 16,
right: 16,
bottom: 8),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.center,
children: <Widget>[],
),
),
],
),
),
),
const SizedBox(
width: 48,
),
],
),
),
),
const SizedBox(
height: 48,
),
],
),
),
),
Container(
child: Padding(
padding: const EdgeInsets.only(top: 24, right: 16, left: 16),
child: Container(
decoration: BoxDecoration(
borderRadius:
const BorderRadius.all(Radius.circular(16.0)),
boxShadow: <BoxShadow>[
BoxShadow(
color: Color(0xFF3A5160).withOpacity(0.2),
offset: const Offset(0.0, 0.0),
blurRadius: 6.0),
],
),
child: ClipRRect(
borderRadius:
const BorderRadius.all(Radius.circular(16.0)),
child: AspectRatio(
aspectRatio: 1,
child: Image(
image: NetworkImage(
widget.item['Age'],
),
fit: BoxFit.fill, // use this
),
),
),
),
),
),
],
),
),
),
);
}
}
我的 SearchBar 被单独调用:
Container(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
onChanged: (value) {
},
controller: editingController,
decoration: InputDecoration(
labelText: "Search",
hintText: "Search",
prefixIcon: Icon(Icons.search),
border: OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(25.0)))),
),
),
],),),
我需要一种制作重复列表的方法来搜索给定列表中的元素并仅显示这些元素。
解决方案
这是一个完整的例子。像这样做:
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
// Main code starts here // Your widget must be stateful
class MyWidget extends StatefulWidget {
@override
createState() => _MyWidgetState();
}
// Here is the list of all your people
List<Map> people = [
{
'name': 'John',
'age': 25
},
{
'name': 'Billy',
'age': 21
},
{
'name': 'Bob',
'age': 18
},
{
'name': 'Kate',
'age': 23
},
{
'name': 'Rose',
'age': 18
},
{
'name': 'David',
'age': 42
},
{
'name': 'Marc',
'age': 42
},
{
'name': 'Sophie',
'age': 38
},
{
'name': 'Bill',
'age': 77
},
];
class _MyWidgetState extends State<MyWidget> {
List<Map> _filtered = people.toList(); // Make a copy of the original list
TextEditingController _controller = TextEditingController();
@override
void dispose() {
_controller.dispose(); // Remember to dispose the controller
super.dispose();
}
// This method filters the '_filtered' list according to the key
void filter(String match) {
setState(() {
_filtered = people
.where((data) => data['name'].toLowerCase().contains(match.toLowerCase()))
.toList();
}); // Set state to notify flutter that the widget must be rebuilt
}
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: TextField(
controller: _controller,
onChanged: filter, // When the text is changed, this method is called, You can do it as lambda too (match) => ....
),
),
SizedBox(height: 20),
Expanded(
// I have used list view but you can use your own widget like a grid view. The idea is same for both cases
child: ListView.builder(
physics: BouncingScrollPhysics(),
itemCount: _filtered.length, // Filtered list length
itemBuilder: (context, i) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(_filtered[i]['name'] + ', Age: ' + _filtered[i]['age'].toString(),), // Put your data this way
);
},
),
)
],
);
}
}
结果如下:
在您开始输入文本后:
推荐阅读
- scala - VSCode metal scala,集成测试文件夹看不到类
- firebase - firebase_auth:当用户被禁用时抛出 PlatfromException 而不是 FirebaseAuthInvalidUserException?
- python - 拆分后如何对文本文件中的数字进行排序
- reactjs - RN(0.61.4) 使用 Salesforce 社区 api 访问时,它以 image/html 的形式出现,它会在 Android 中自动显示 Image,但在 ios 中不显示
- ibeacon-android - 离开信标区域时触发 didEnterRegion 事件
- sql - 如何使用列中的 MAX 值更新列以添加自动增量?
- angular - 使 ngx-perfect-scrollbar 默认可见
- css - Safari浏览器在调用新站点时停止css动画
- java - JSON to Avro conversion exception - Expected start-union. Got VALUE_STRING
- asp.net-core - Error While trying to view PDF document in browser it just get downloaded [ASP.net Core 3.0]