Flutter收藏库——简单的搜索功能
2020-05-22 本文已影响0人
_破晓之翼
最近在做项目时需要用到搜索框搜索功能,百度后记之以温习。
实现搜索功能的SearchDelegate
实现搜索功能的原理简单来说,就是在点击搜索框时调用了showSearch(context: context,
delegate: SearchBarDelegate())方法跳转到搜索界面。
在SearchDelegate<T>中定义了如下几个方法,我们使用时可将它重写:
class SearchBarDelegate extends SearchDelegate<String> {
//返回值为我们搜索框右侧的一个控件
@override
List<Widget> buildActions(BuildContext context) {
return null;
}
//返回值为我们搜索框左侧的一个控件
@override
Widget buildLeading(BuildContext context) {
return null;
}
//返回值为我们搜到内容后的展现
@override
Widget buildResults(BuildContext context) {
return null;
}
//设置推荐
@override
Widget buildSuggestions(BuildContext context) {
return null;
}
//返回一个主题,也就是可以自定义搜索界面的主题样式
@override
ThemeData appBarTheme(BuildContext context) {
// TODO: implement appBarTheme
return super.appBarTheme(context);
}
}
Demo演示
这是搜索框所在的界面:

自定义搜索框代码如下:
Scaffold(
appBar: AppBar(
title: Padding(
padding: EdgeInsets.only(top: 2,bottom: 2,left: 16),
child: Container(
height: 35,
width: MediaQuery.of(context).size.width-64,
decoration: BoxDecoration(
color: Color.fromRGBO(230,230,230,1.0),
borderRadius: BorderRadius.circular(20)
),
child: InkWell(
child: Row(
children: <Widget>[
Padding(padding: EdgeInsets.only(left: 10,right: 10),
child: Icon(Icons.search,color: Colors.teal)),
Text("点我进行搜索",style: TextStyle(color: Colors.grey,fontSize: 15),)
],
),
onTap: (){
//这里是跳转搜索界面的关键
showSearch(context: context,delegate: SearchBarDelegate());
},
),
),
)
),
);
点击搜索框后会执行showSearch(context: context,delegate: SearchBarDelegate());
跳转到搜索界面。
一般数据都是从后端来,这里没有后端我就用简单的几个蔬菜做为例子。
var nameList = [
"绿皮南瓜","番茄", "白菜", "胡萝卜","土豆","甜菜","白甜"
];
bool flag;//判断搜索框内输入的内容是否存在于数据列表里

重写buildActions方法(搜索框右侧的一个控件):
这里我设置了一个叉按钮,用于清空搜索框里面的内容。
@override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
showSuggestions(context);
}, //搜索值为空
)
];
}
重写buildLeading方法(搜索框左侧的一个控件):
这里我在网上趴了个带动画的返回按钮,返回至上一个页面。
@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, progress: transitionAnimation
),
onPressed: () => close(context, null) //点击时关闭整个搜索页面
);
}
重新buildResults方法(搜到内容后的展现):
(注:query为我们在搜索框内输入的内容)
这里先判断了我们输入的数据是否存在于数据列表里,如果存在那么将展示搜索出来的结果,如果不存在则展示没有找到。
@override
Widget buildResults(BuildContext context) {
for(int i=0;i<nameList.length;i++){
if(query==nameList[i]){
flag = true;
break;
}
else{
flag = false;
}
}
return flag == true ? Padding(
padding: EdgeInsets.all(16),
child: InkWell(
child: Text(query),
onTap: (){
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new TextScreen(s: query),
//TextScreen()用于展示我们想要通过搜索到达的页面,
//这里用到了构造函数传值。
),
);
},
))
:
Center(
child: Text("没有找到这个蔬菜!!!"),
);
}
重写buildSuggestions方法(设置推荐):
(注:这里的suggestionsList和recentSuggest我把他们设置成了和nameList一样的内容)
在这里的RichText用于显示不同的样式的文字,当我们输入首个关键字时,它会补全我们输入的内容。
@override
Widget buildSuggestions(BuildContext context) {
final suggestionsList= query.isEmpty ? recentSuggest
:
searchList.where((input)=> input.startsWith(query)).toList();
//判断集合中的字符串是否以搜索框内输入的字符串开头,
//是则返回true,并将筛选出来的结果以list的方式储存在searchList里
return ListView.builder(
itemCount:suggestionsList.length,
itemBuilder: (context,index) {
return InkWell(
child: ListTile(
title: RichText( //富文本
text: TextSpan(
text: suggestionsList[index].substring(0,query.length),
style: TextStyle(color: Colors.black,fontWeight: FontWeight.bold),
children: [
TextSpan(
text: suggestionsList[index].substring(query.length),
style: TextStyle(color: Colors.grey)
)
]
),
),
),
onTap: (){
Navigator.push(
context,
new MaterialPageRoute(
builder: (context) => new TextScreen(s: suggestionsList[index]),
),
);
},
);
}
);
}
我们想要通过搜索到达的页面:
class TextScreen extends StatelessWidget {
final String s;
TextScreen({Key key, @required this.s}) : super(key: key);
@override
Widget build(BuildContext context) {
// Use the Todo to create our UI
return new Scaffold(
appBar: AppBar(
title: Text("搜索结果内容"),
),
body: Padding(
padding: EdgeInsets.all(16.0),
child: Center(
child: Text(s),
)
),
);
}
}
最后的成品展示:

OVER~
在这里https://www.jianshu.com/p/63aca25a463c学习了