Flutter 如何在 Flutter 搜索过滤结果无结果时显示消息
Flutter How to show a message when flutter search filter result no result
我使用 TextFormField
过滤列表数组,使用 GridView
显示项目。在我的 TextFormField
中,我使用了 onChanged: onSearchTextChanged,
来过滤来自我在 json
中创建的 Rest API 的数组响应。过滤器工作正常,但我正在寻找一种方法来解决当用户输入过滤器内部不可用的过滤器时不显示结果的问题。下面是我的代码:
TextFormField如下:
TextFormField(
controller: controller,
keyboardType: TextInputType.text,
onChanged: onSearchTextChanged,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
prefixText: ' ',
hintText: "Search",
hintStyle: TextStyle(
color: Colors.grey,fontWeight: FontWeight.normal,
fontSize: 15,
fontFamily:
'Montserrat'),
prefixIcon: Container(
child:Icon(
Icons.search,
color: Colors.grey,
size: 20,
)),
suffixIcon: backClear==true?InkWell(
onTap: () {
controller.clear();
onSearchTextChanged(
'');
},
child: Container(
child:Icon(
Icons.backspace,
color: Colors.grey,
size: 12,
))): Container(
child:Icon(
Icons.view_list_rounded,
color: Colors.grey,
size: 15,
)),
labelStyle: new TextStyle(color: Colors.grey),
),
)
onSearchTextChanged 如下:
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {
backClear=false;
});
return;
}
content.forEach((userDetail) {
if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
userDetail.email.toUpperCase().contains(text) ) {
_searchResult.add(userDetail);
}
});
setState(() {
backClear=true;
});
}
例如,如果 John
不是 username, fullname
的 return 数组列表的一部分,那么在屏幕上它应该显示一条消息说 not found
。
我的gridview如下:
Container(
child: _searchResult.length != 0 ||
controller.text.isNotEmpty
?new GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _searchResult == null ? 0 : _searchResult.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
itemBuilder: (BuildContext context, int index){
return Card(
elevation: 1,
semanticContainer: true,
child:InkWell(
onTap: () async {
},
child: Container(
padding: EdgeInsets.all(10),
child:Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.bottomCenter,
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: _searchResult[index].profile_img!=null?Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:NetworkImage(_searchResult[index].profile_img
,),
backgroundColor: Colors.white,
//
)):Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:AssetImage('assets/person_icon.png'),
backgroundColor: Colors.white,
//
)),
),
],),
Flexible(
child: Center(child: Text(_searchResult[index].username==null?"AppName":_searchResult[index].username,style: TextStyle(
color: colorBlack,
fontWeight: FontWeight.normal,
fontSize: 10,
fontFamily: 'Montserrat',
),))),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
decoration: BoxDecoration(
color: colorBlue,borderRadius: BorderRadius.circular(3)),
child: Text( "Follow",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 10,
fontFamily: 'Montserrat',
),
),
),)
],
),
),
]))));
;})
:GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: content == null ? 0 : content.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
itemBuilder: (BuildContext context, int index){
return Card(
elevation: 1,
semanticContainer: true,
child:InkWell(
onTap: () async {
},
child: Container(
padding: EdgeInsets.all(10),
child:Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.bottomCenter,
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: content[index].profile_img!=null?Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:NetworkImage(content[index].profile_img
,),
backgroundColor: Colors.white,
//
)):Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:AssetImage('assets/person_icon.png'),
backgroundColor: Colors.white,
//
)),
),
],),
Flexible(
child: Center(child: Text(content[index].username==null?"AppName":content[index].username,style: TextStyle(
color: colorBlack,
fontWeight: FontWeight.normal,
fontSize: 10,
fontFamily: 'Montserrat',
),))),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
decoration: BoxDecoration(
color: colorBlue,borderRadius: BorderRadius.circular(3)),
child: Text( "Follow",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 10,
fontFamily: 'Montserrat',
),
),
),)
],
),
),
]))));}))
我不确定您在示例代码中实际显示结果的位置,但您可以实现的逻辑如下。
在 forEach
之后,您应该检查是否确实找到了某些结果,如果没有,将 showNotFoundText
设置为 true 以便在您的视图中显示消息。
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {
backClear=false;
showNotFoundText = false;
});
return;
}
content.forEach((userDetail) {
if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
userDetail.email.toUpperCase().contains(text) ) {
_searchResult.add(userDetail);
}
});
if (_searchResult.isEmpty) {
//Do something
setState(() {
showNotFoundText = true;
});
}
setState(() {
backClear=true;
});
}
在您的视图中添加类似的内容
showNotFoundText ? Text("No results found") : Container() //Empty container instead
由于你没有包含结果显示的代码,我是这样写的,但你也可以考虑直接在你的视图中使用这个逻辑:
_searchResult.isEmpty ? Text("No results found") : DisplayResultsWidget()
根据 Dani3le_
的建议,在我的 onSearchTextChanged
中使用 add below if
语句,并且我在我的代码
上方声明了我的 bool showNotFoundText = false;
if (_searchResult.isEmpty) {
//Do something
setState(() {
showNotFoundText = true;
});
}
在我的 Gridview
之上,我添加了以下内容以显示代码下方的 No result message
查找:
showNotFoundText==true ? Text("No result found!",style: TextStyle(fontFamily: 'Montserrat',color: Colors.grey, fontSize: 13, fontWeight: FontWeight.bold),) : Container(),
但是 onPress
的退格键 No result found
仍然显示,即使输入在搜索列表中可用所以我将 showNotFoundText = false;
添加到 setState()
这样每次按下退格键将 showNotFoundText
的状态设置回 false
,如下所示:
setState(() {
showNotFoundText = false;
});
我使用 TextFormField
过滤列表数组,使用 GridView
显示项目。在我的 TextFormField
中,我使用了 onChanged: onSearchTextChanged,
来过滤来自我在 json
中创建的 Rest API 的数组响应。过滤器工作正常,但我正在寻找一种方法来解决当用户输入过滤器内部不可用的过滤器时不显示结果的问题。下面是我的代码:
TextFormField如下:
TextFormField(
controller: controller,
keyboardType: TextInputType.text,
onChanged: onSearchTextChanged,
decoration: InputDecoration(
border: InputBorder.none,
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
prefixText: ' ',
hintText: "Search",
hintStyle: TextStyle(
color: Colors.grey,fontWeight: FontWeight.normal,
fontSize: 15,
fontFamily:
'Montserrat'),
prefixIcon: Container(
child:Icon(
Icons.search,
color: Colors.grey,
size: 20,
)),
suffixIcon: backClear==true?InkWell(
onTap: () {
controller.clear();
onSearchTextChanged(
'');
},
child: Container(
child:Icon(
Icons.backspace,
color: Colors.grey,
size: 12,
))): Container(
child:Icon(
Icons.view_list_rounded,
color: Colors.grey,
size: 15,
)),
labelStyle: new TextStyle(color: Colors.grey),
),
)
onSearchTextChanged 如下:
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {
backClear=false;
});
return;
}
content.forEach((userDetail) {
if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
userDetail.email.toUpperCase().contains(text) ) {
_searchResult.add(userDetail);
}
});
setState(() {
backClear=true;
});
}
例如,如果 John
不是 username, fullname
的 return 数组列表的一部分,那么在屏幕上它应该显示一条消息说 not found
。
我的gridview如下:
Container(
child: _searchResult.length != 0 ||
controller.text.isNotEmpty
?new GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: _searchResult == null ? 0 : _searchResult.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
itemBuilder: (BuildContext context, int index){
return Card(
elevation: 1,
semanticContainer: true,
child:InkWell(
onTap: () async {
},
child: Container(
padding: EdgeInsets.all(10),
child:Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.bottomCenter,
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: _searchResult[index].profile_img!=null?Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:NetworkImage(_searchResult[index].profile_img
,),
backgroundColor: Colors.white,
//
)):Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:AssetImage('assets/person_icon.png'),
backgroundColor: Colors.white,
//
)),
),
],),
Flexible(
child: Center(child: Text(_searchResult[index].username==null?"AppName":_searchResult[index].username,style: TextStyle(
color: colorBlack,
fontWeight: FontWeight.normal,
fontSize: 10,
fontFamily: 'Montserrat',
),))),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
decoration: BoxDecoration(
color: colorBlue,borderRadius: BorderRadius.circular(3)),
child: Text( "Follow",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 10,
fontFamily: 'Montserrat',
),
),
),)
],
),
),
]))));
;})
:GridView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: content == null ? 0 : content.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount:3),
itemBuilder: (BuildContext context, int index){
return Card(
elevation: 1,
semanticContainer: true,
child:InkWell(
onTap: () async {
},
child: Container(
padding: EdgeInsets.all(10),
child:Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Stack(
alignment: Alignment.bottomCenter,
children: [
CircleAvatar(
radius: 30,
backgroundColor: Colors.white,
child: content[index].profile_img!=null?Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:NetworkImage(content[index].profile_img
,),
backgroundColor: Colors.white,
//
)):Container(
padding: EdgeInsets.all(0),
child:CircleAvatar(
radius: 40,
backgroundImage:AssetImage('assets/person_icon.png'),
backgroundColor: Colors.white,
//
)),
),
],),
Flexible(
child: Center(child: Text(content[index].username==null?"AppName":content[index].username,style: TextStyle(
color: colorBlack,
fontWeight: FontWeight.normal,
fontSize: 10,
fontFamily: 'Montserrat',
),))),
Flexible(
child: Container(
padding: EdgeInsets.only(left: 15,right: 15,top: 1,bottom: 1),
decoration: BoxDecoration(
color: colorBlue,borderRadius: BorderRadius.circular(3)),
child: Text( "Follow",
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 10,
fontFamily: 'Montserrat',
),
),
),)
],
),
),
]))));}))
我不确定您在示例代码中实际显示结果的位置,但您可以实现的逻辑如下。
在 forEach
之后,您应该检查是否确实找到了某些结果,如果没有,将 showNotFoundText
设置为 true 以便在您的视图中显示消息。
onSearchTextChanged(String text) async {
_searchResult.clear();
if (text.isEmpty) {
setState(() {
backClear=false;
showNotFoundText = false;
});
return;
}
content.forEach((userDetail) {
if (userDetail.username.toLowerCase().contains(text) || userDetail.username.toString().contains(text) ||
userDetail.username.toUpperCase().contains(text)||userDetail.fullname.toLowerCase().contains(text) || userDetail.fullname.toString().contains(text) ||
userDetail.fullname.toUpperCase().contains(text)||userDetail.phone.toLowerCase().contains(text) || userDetail.phone.toString().contains(text) ||
userDetail.phone.toUpperCase().contains(text)||userDetail.email.toLowerCase().contains(text) || userDetail.email.toString().contains(text) ||
userDetail.email.toUpperCase().contains(text) ) {
_searchResult.add(userDetail);
}
});
if (_searchResult.isEmpty) {
//Do something
setState(() {
showNotFoundText = true;
});
}
setState(() {
backClear=true;
});
}
在您的视图中添加类似的内容
showNotFoundText ? Text("No results found") : Container() //Empty container instead
由于你没有包含结果显示的代码,我是这样写的,但你也可以考虑直接在你的视图中使用这个逻辑:
_searchResult.isEmpty ? Text("No results found") : DisplayResultsWidget()
根据 Dani3le_
的建议,在我的 onSearchTextChanged
中使用 add below if
语句,并且我在我的代码
bool showNotFoundText = false;
if (_searchResult.isEmpty) {
//Do something
setState(() {
showNotFoundText = true;
});
}
在我的 Gridview
之上,我添加了以下内容以显示代码下方的 No result message
查找:
showNotFoundText==true ? Text("No result found!",style: TextStyle(fontFamily: 'Montserrat',color: Colors.grey, fontSize: 13, fontWeight: FontWeight.bold),) : Container(),
但是 onPress
的退格键 No result found
仍然显示,即使输入在搜索列表中可用所以我将 showNotFoundText = false;
添加到 setState()
这样每次按下退格键将 showNotFoundText
的状态设置回 false
,如下所示:
setState(() {
showNotFoundText = false;
});