[英]Flutter - TextField how to filter list
我是 Flutter 的新手,我试图了解事情是如何运作的。
我创建了一个应该显示商店列表的简单应用程序,据我所知,我需要整个屏幕滚动,我不能使用ListView
。
我还添加了一个TextField
,我想用它来过滤内容,以便用户可以看到他想要的商店。
这是我的代码:
import 'package:testapp/models/maison.dart';
import 'package:testapp/widgets/maison_card.dart';
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController _searchTextController = new TextEditingController();
String filter;
List<Maison> _maisons = maisons;
@override
void initState() {
super.initState();
_searchTextController.addListener(() {
print(_searchTextController.text);
filter = _searchTextController.text;
});
}
@override
void dispose() {
_searchTextController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.width * 0.70,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0.0, 2.0),
blurRadius: 6.0,
)
],
),
child: Image(
image: AssetImage('assets/images/bg-home.png'),
fit: BoxFit.cover,
),
),
Transform.translate(
offset: Offset(0, -25),
child: Container(
height: 60.0,
padding: EdgeInsets.only(left: 20, top: 8),
margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey[350],
blurRadius: 20.0,
offset: Offset(0, 10.0),
),
],
),
child: TextField(
controller: _searchTextController,
decoration: InputDecoration(
suffixIcon: Icon(
Icons.search,
color: Colors.black,
size: 20.0,
),
border: InputBorder.none,
hintText: 'Cerca la maison',
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
),
child: Row(
children: <Widget>[
Text(
"Le Maison",
style: Theme.of(context).textTheme.headline1,
),
Spacer(),
],
),
),
..._maisons.map((Maison m) {
return filter == null || filter == ''
? MaisonCard(maison: m)
: m.name.toLowerCase().contains(filter.toLowerCase())
? MaisonCard(maison: m)
: Container();
}).toList(),
],
),
);
}
}
最后我有这个:
..._maisons.map((Maison m) {
return filter == null || filter == ''
? MaisonCard(maison: m)
: m.name.toLowerCase().contains(filter.toLowerCase())
? MaisonCard(maison: m)
: Container();
}).toList(),
这应该根据filter
值打印商店列表。
我认为问题在于小部件树已经构建,因此如果我键入一些文本,则不会再次打印树。
还有另一种方法可以完成这项任务吗?
Maisons 是一个简单的 class:
import 'package:flutter/material.dart';
class Maison {
final String id;
final String name;
final String imageUrl;
Maison({
@required this.id,
@required this.name,
@required this.imageUrl,
});
}
List<Maison> maisons = [
Maison(
id: '1',
name: 'Armani',
imageUrl:
'https://images.unsplash.com/photo-1495562569060-2eec283d3391?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
),
Maison(
id: '2',
name: 'Dolce & Gabbana',
imageUrl:
'https://images.unsplash.com/photo-1582559934353-2e47140e7501?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1788&q=80',
),
Maison(
id: '3',
name: 'Zegna',
imageUrl:
'https://images.unsplash.com/photo-1553355617-f7342d67a95f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
),
Maison(
id: '4',
name: 'Cavalli',
imageUrl:
'https://images.unsplash.com/photo-1555141816-810dd5692b6a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1789&q=80',
),
];
您可以在下面复制粘贴运行完整代码
你可以调用setState(() {});
在addListener
代码片段
_searchTextController.addListener(() {
print(_searchTextController.text);
filter = _searchTextController.text;
setState(() {});
});
工作演示
完整代码
import 'package:flutter/material.dart';
class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
TextEditingController _searchTextController = new TextEditingController();
String filter;
List<Maison> _maisons = maisons;
@override
void initState() {
super.initState();
_searchTextController.addListener(() {
print(_searchTextController.text);
filter = _searchTextController.text;
setState(() {});
});
}
@override
void dispose() {
_searchTextController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: MediaQuery.of(context).size.width * 0.70,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black26,
offset: Offset(0.0, 2.0),
blurRadius: 6.0,
)
],
),
child: Image(
image: NetworkImage('https://picsum.photos/250?image=9'),
fit: BoxFit.cover,
),
),
Transform.translate(
offset: Offset(0, -25),
child: Container(
height: 60.0,
padding: EdgeInsets.only(left: 20, top: 8),
margin: EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
boxShadow: [
BoxShadow(
color: Colors.grey[350],
blurRadius: 20.0,
offset: Offset(0, 10.0),
),
],
),
child: TextField(
controller: _searchTextController,
decoration: InputDecoration(
suffixIcon: Icon(
Icons.search,
color: Colors.black,
size: 20.0,
),
border: InputBorder.none,
hintText: 'Cerca la maison',
),
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 16.0,
right: 16.0,
),
child: Row(
children: <Widget>[
Text(
"Le Maison",
style: Theme.of(context).textTheme.headline2,
),
Spacer(),
],
),
),
..._maisons.map((Maison m) {
return filter == null || filter == ''
? MaisonCard(maison: m)
: m.name.toLowerCase().contains(filter.toLowerCase())
? MaisonCard(maison: m)
: Container();
}).toList(),
],
),
);
}
}
Widget MaisonCard({Maison maison}) {
return Card(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
ListTile(
leading: Icon(Icons.album),
title: Text('${maison.name}'),
subtitle: Text('${maison.id}'),
),
],
),
);
}
class Maison {
final String id;
final String name;
final String imageUrl;
Maison({
@required this.id,
@required this.name,
@required this.imageUrl,
});
}
List<Maison> maisons = [
Maison(
id: '1',
name: 'Armani',
imageUrl:
'https://images.unsplash.com/photo-1495562569060-2eec283d3391?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
),
Maison(
id: '2',
name: 'Dolce & Gabbana',
imageUrl:
'https://images.unsplash.com/photo-1582559934353-2e47140e7501?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1788&q=80',
),
Maison(
id: '3',
name: 'Zegna',
imageUrl:
'https://images.unsplash.com/photo-1553355617-f7342d67a95f?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80',
),
Maison(
id: '4',
name: 'Cavalli',
imageUrl:
'https://images.unsplash.com/photo-1555141816-810dd5692b6a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1789&q=80',
),
];
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(
title: "test",
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: HomePage(),
);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.