搜索栏是大部分APP都包括的组件,实际开发中需要这个搜索栏,网上阅读了一些资料后。实现flutter的搜索栏。Flutter为我们提供了这个组件SearchDelegate,先看一下效果图哦。
一、定义SearchDelegate
class searchBarDelegate extends SearchDelegate<String> {
/*这个方法返回一个控件列表,显示为搜索框右边的图标按钮,这里设置为一个清除按钮,并且在搜索内容为空的时候显示建议搜索内容,使用的是showSuggestions(context)方法:*/
@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);
}
}
实现代码:
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:ws/common/dao/expense_dao.dart';
import 'package:ws/model/expense_model.dart';
import 'package:ws/redux/ws_state.dart';
import 'package:ws/widget/ws_no_data.dart';
class ExpenseSearch extends SearchDelegate<String>{
String searchHint = "请输入搜索内容...";
var monthList = [
"一月",
"二月",
"三月",
"四月",
"五月",
"六月",
"七月",
"八月",
"九月",
"十月",
"十一月",
"十二月",
];
var typeList = [
"差旅费报销单",
"一般费用报销单",
"因公临时出国(境)支出表",
"药费报销单",
"合同付款审批表",
"工资系统专用报销表",
];
List<ExpenseList> items = new List<ExpenseList>();
@override
String get searchFieldLabel => searchHint;
@override
List<Widget> buildActions(BuildContext context) {
// TODO: implement buildActions
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
showSuggestions(context);
},
),
];
}
@override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow, progress: transitionAnimation),
onPressed: () {
if (query.isEmpty) {
close(context, null);
} else {
query = "";
showSuggestions(context);
}
},
);
}
@override
Widget buildResults(BuildContext context) {
return FutureBuilder(
future: _loadData(),
builder: (context, AsyncSnapshot snapshot) {
return StoreBuilder<WSState>(
builder: (context, store) {
return ListView.builder(
physics: AlwaysScrollableScrollPhysics(),
itemCount: items?.length == 0 ? 1 : items.length,
itemBuilder: (BuildContext context, int index) {
if (items.length > 0) {
ExpenseList expenseList = items[index];
return ListTile(
title:Text(expenseList.title),
subtitle: Text(expenseList.content),
);
} else {
return NoData();
}
});
});
}
);
///展示搜索结果
}
@override
Widget buildSuggestions(BuildContext context) {
return Container(
margin: EdgeInsets.only(left: 16.0, right: 16.0),
child: ListView(
primary: false,
shrinkWrap: true,
children: <Widget>[
SizedBox(height: 10.0),
Text(
"报销月份:",
style: TextStyle(fontSize: 20),
),
SizedBox(height: 10.0),
Wrap(
spacing: 8.0,
runSpacing: 8.0,
children: monthList.map((childNode) {
return InkWell(
child: new ClipRRect(
borderRadius: BorderRadius.circular(3.0),
child: Container(
padding: EdgeInsets.all(3.0),
color:Colors.grey,
child: Text(
childNode,
style: TextStyle(
fontSize: 16,
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey, offset: Offset(0.2, 0.2))
],
),
),
),
),
onTap: () {
_loadData();
Future.delayed( Duration(seconds: 2), () async {
searchHint = "";
query = childNode;
showResults(context);
});
},
);
}).toList(),
),
SizedBox(height: 10.0),
Text(
"报销类型:",
style: TextStyle(fontSize: 18),
),
SizedBox(height: 10.0),
Wrap(
spacing: 8.0,
runSpacing: 8.0,
children: typeList.map((childNode) {
return InkWell(
child: new ClipRRect(
borderRadius: BorderRadius.circular(3.0),
child: Container(
padding: EdgeInsets.all(3.0),
color:Colors.grey,
child: Text(
childNode,
style: TextStyle(
fontSize: 16,
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey, offset: Offset(0.2, 0.2))
],
),
),
),
),
onTap: () {
_loadData();
Future.delayed( Duration(seconds: 2), () async {
searchHint = "";
query = childNode;
showResults(context);
});
},
);
}).toList(),
),
],
),
);
}
_loadData() async {
//网络加载
var data = await ExpenseDao.getInitExpense(1, 20);
Expense expense = Expense.fromJson(data);
items=expense.list;
}
}