在 Flutter 的 SearchBar 中搜索期间,搜索项没有显示?
Search Items are not showing up during search in SearchBar in Flutter?
我想在 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(),
],
),
);
}
我只想根据标题在flutter中搜索ListTile widget
您还可以看到我上传的图片,它显示我实现了可以在搜索栏中输入内容的情况。现在我只需要将输入文本与 ListTile 的标题进行比较,并显示匹配的图块。
我已经创建了一个不同的列表 class like----
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.It 的位置显示错误“列表类型的值无法分配给列表类型的变量 class.
你有一个 List<Blog>
某处叫做 allblogs
。每次搜索文本更改时都会形成一个新的子列表,如下所示:
List<Blog> sublist = allblogs.where((b) => b.name.toLowerCase().contains(_searchText.toLowerCase())).toList();
(如果搜索文本为空,则只需将所有博客分配给子列表)
现在在您当前在构建中使用 allblogs
的任何地方都使用 sublist
。
因此,每次更改搜索条件时,您都会将完整列表过滤到匹配的子列表,并且(只要您在 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();
}
});
},
),
],
);
}
}
我想在 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(),
],
),
);
}
我只想根据标题在flutter中搜索ListTile widget
您还可以看到我上传的图片,它显示我实现了可以在搜索栏中输入内容的情况。现在我只需要将输入文本与 ListTile 的标题进行比较,并显示匹配的图块。
我已经创建了一个不同的列表 class like----
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.It 的位置显示错误“列表类型的值无法分配给列表类型的变量 class.
你有一个 List<Blog>
某处叫做 allblogs
。每次搜索文本更改时都会形成一个新的子列表,如下所示:
List<Blog> sublist = allblogs.where((b) => b.name.toLowerCase().contains(_searchText.toLowerCase())).toList();
(如果搜索文本为空,则只需将所有博客分配给子列表)
现在在您当前在构建中使用 allblogs
的任何地方都使用 sublist
。
因此,每次更改搜索条件时,您都会将完整列表过滤到匹配的子列表,并且(只要您在 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();
}
});
},
),
],
);
}
}