我有一个listView,它表示为gridView。我添加了一个带有TextController的搜索栏。
网格 View 具有各个元素,这些元素具有名称和年龄。我希望搜索查询搜索名称并仅显示相关元素。
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
);
},
),
)
],
);
}
}
结果如下:
在您开始输入文字之后:
关于flutter - 如何在ListView中搜索特定元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60262736/