我想在Flutter中添加搜索栏。我已经达到了可以在搜索栏中键入内容的状态,但是在编写查询期间,列表未更新。
我想基于blogName排序,下面是代码
class AllBlogs extends StatefulWidget {
AllBlogs({Key key}) : super(key: key);
final Color _tabBackgroudColor = const Color(0xFF1A237E);
@override
AllBlogsState createState() {
return new AllBlogsState();
}
}
class AllBlogsState extends State<AllBlogs> {
Widget appBarTitle = Text("Blog's List");
Icon actionIcon = Icon(Icons.search, color: Colors.white,);
final key = new GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = new TextEditingController();
bool _IsSearching;
String _searchText = "";
_SearchListState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_IsSearching = false;
_searchText = "";
});
}
else {
setState(() {
_IsSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
@override
void initState() {
// TODO: implement initState
super.initState();
_IsSearching = false;
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: buildBar(context),
body: new Container(
color: Colors.transparent,
child: ListView.builder(
itemCount: allblogs.length,
// Facing Issue Here
itemBuilder: _IsSearching ? buildSearchList : blogslist
),
),
);
}
// Facing Issue Here
Widget buildSearchList(BuildContext context, int index){
if (_searchText.isEmpty){
return blogslist(context, index);
}
else {
List<String> _searchList = List();
for (int i = 0; i < allblogs.length; i++) {
String name = (allblogs[index].blogName);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
// Now what can i return to show the tile whoes blogName I searched for
);
}
}
Widget buildBar(BuildContext context) {
return AppBar(
centerTitle: true,
title: appBarTitle,
backgroundColor: widget._tabBackgroudColor,
actions: <Widget>[
IconButton(icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
// ignore: new_with_non_type
this.actionIcon = new Icon(Icons.close, color: Colors.white,);
this.appBarTitle = TextField(
controller: _searchQuery,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: TextStyle(color: Colors.white)
),
);
_handleSearchStart();
}
else {
_handleSearchEnd();
}
});
},),
],
);
}
void _handleSearchStart() {
setState(() {
_IsSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
// ignore: new_with_non_type
this.actionIcon = new Icon(Icons.search, color: Colors.white,);
this.appBarTitle = new Text("Search Sample", style: TextStyle(
color: Colors.white,
),);
_IsSearching = false;
_searchQuery.clear();
});
}
}
Widget blogslist(BuildContext context, int index){
return Container(
padding: const EdgeInsets.only(top: 5.0),
child: Column(
children: <Widget>[
ListTile(
leading: Padding(
padding: const EdgeInsets.all(3.0),
child: new Image(image: AssetImage("assets/images/icons/stackexchange.png")),
),
title: Text(allblogs[index].blogName,
),
subtitle: Text(allblogs[index].blogName),
contentPadding: EdgeInsets.symmetric(horizontal: 3.0),
isThreeLine: true,
trailing: Padding(padding: const EdgeInsets.only(left: 5.0),
child: IconButton(icon: Icon(Icons.launch, color: Colors.blue, size: 20.0,),
onPressed: (){}),
),
),
Divider(),
],
),
);
}
我想要做的就是根据标题在扑扑中搜索ListTile小部件 您还可以看到我上传的图像,显示我已经完成了可以在搜索栏中键入内容的情况。现在,我只需要将输入文本与ListTile的标题进行比较,并显示匹配的图块。
我创建了一个不同类的列表,例如
class AllBlogs {
final String id;
final String blogName;
final String blogurl;
final String about;
const AllBlogs(
{@required this.id,
@required this.blogName,
@required this.blogurl,
@required this.about});
}
List<AllBlogs> allblogs = [
const AllBlogs(
id: '1',
blogName: 'KDnuggets',
blogurl: "https://www.kdnuggets.com/?ref=cybrhome",
about: "KDnuggets is one of the most popular data science blogs, with articles that cover Business Analytics, Statistics, and Machine Learning.",
),
当我尝试编写下面的代码时,然后在allblogs处显示错误信息:``无法将List类型的值分配给List类类型的变量。
答案 0 :(得分:0)
您在某个List<Blog>
处有一个allblogs
。每次搜索文本更改都会形成一个新的子列表,如下所示:
List<Blog> sublist = allblogs.where((b) => b.name.toLowerCase().contains(_searchText.toLowerCase())).toList();
(如果搜索文本为空,则只需将所有博客分配给子列表)
现在在您当前在构建中使用sublist
的任何地方使用allblogs
。
因此,对搜索条件的每次更改,都将整个列表过滤到与之匹配的子列表中,并且(只要您在setState中执行此操作),Widget树就会重绘,仅显示过滤后的列表。
这是一个根据您的上面的片段的完整工作示例:
import 'package:flutter/material.dart';
main() {
runApp(new MaterialApp(
title: 'Blogs Test',
home: new AllBlogs(),
));
}
class Blog {
String blogName;
Blog(this.blogName);
}
List<Blog> allblogs = [
Blog('flutter'),
Blog('dart'),
Blog('java'),
Blog('python'),
];
class AllBlogs extends StatefulWidget {
AllBlogs({Key key}) : super(key: key);
final Color _tabBackgroundColor = const Color(0xFF1A237E);
@override
AllBlogsState createState() => AllBlogsState();
}
class AllBlogsState extends State<AllBlogs> {
Widget appBarTitle = Text("Blog's List");
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = new GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = new TextEditingController();
List<Blog> _displayList = allblogs;
@override
void initState() {
super.initState();
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_displayList = allblogs;
});
} else {
setState(() {
String s = _searchQuery.text;
_displayList = allblogs
.where((b) => b.blogName.toLowerCase().contains(s.toLowerCase()))
.toList();
});
}
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: buildBar(context),
body: new Container(
color: Colors.transparent,
child: ListView.builder(
itemCount: _displayList.length,
itemBuilder: _blogBuilder,
),
),
);
}
Widget _blogBuilder(BuildContext context, int index) {
return Container(
padding: const EdgeInsets.only(top: 5.0),
child: Column(
children: <Widget>[
ListTile(
leading: Padding(
padding: const EdgeInsets.all(3.0),
child: new Image(
image: AssetImage("assets/images/icons/stackexchange.png")),
),
title: Text(_displayList[index].blogName),
subtitle: Text(_displayList[index].blogName),
contentPadding: EdgeInsets.symmetric(horizontal: 3.0),
isThreeLine: true,
trailing: Padding(
padding: const EdgeInsets.only(left: 5.0),
child: IconButton(
icon: Icon(
Icons.launch,
color: Colors.blue,
size: 20.0,
),
onPressed: () {}),
),
),
Divider(),
],
),
);
}
Widget buildBar(BuildContext context) {
return AppBar(
centerTitle: true,
title: appBarTitle,
backgroundColor: widget._tabBackgroundColor,
actions: <Widget>[
IconButton(
icon: actionIcon,
onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(
Icons.close,
color: Colors.white,
);
this.appBarTitle = TextField(
controller: _searchQuery,
style: TextStyle(
color: Colors.white,
),
decoration: InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "Search...",
hintStyle: TextStyle(color: Colors.white)),
);
} else {
this.actionIcon = new Icon(
Icons.search,
color: Colors.white,
);
this.appBarTitle = new Text(
"Search Sample",
style: TextStyle(
color: Colors.white,
),
);
_searchQuery.clear();
}
});
},
),
],
);
}
}