flutter 右侧实现多条件的筛选效果。效果图
实现要求:
1、两种类型筛选条件数据源。
2、报销月份每行展示3列,可折叠。
3、报销类型,badge长度自适应。
modle 类search.dart
class Search {
String code;
bool check;
Search({this.code, this.check});
Search.fromJson(Map<String, dynamic> json) {
code = json['code'];
check = json['check'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['code'] = this.code;
data['check'] = this.check;
return data;
}
}
drawer_search.dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:ws/common/config/config.dart';
import 'package:ws/common/local/local_storage.dart';
import 'package:ws/common/style/style.dart';
import 'package:ws/model/search.dart';
import 'package:ws/redux/ws_state.dart';
class DrawerSearch extends StatefulWidget {
List<Search> typeList;
List<Search> monthList;
DrawerSearch(this.typeList,this.monthList);
@override
State<StatefulWidget> createState() => _DrawerSearchState();
}
class _DrawerSearchState extends State<DrawerSearch> {
List<Search> monthList = List<Search>();
List<String> monthResult = List<String>();
List<Search> typeList = List<Search>();
List<String> typeResult = List<String>();
bool _isHideValue = true;
@override
void initState() {
// TODO: implement initState
super.initState();
_loadData();
}
@override
Widget build(BuildContext context) {
return StoreBuilder<WSState>(
builder: (context, store) {
return Drawer(
//侧边栏 DraWer
child: Scaffold(
appBar: AppBar(
title: Text('条件过滤'),
),
body: Container(
margin: EdgeInsets.only(left: 16.0, right: 16.0),
child: ListView(
primary: false,
shrinkWrap: true,
children: <Widget>[
SizedBox(height: 10.0),
Column(
children: <Widget>[
Container(
height: 40,
child:GestureDetector(
onTap: (){
setState(() {
_isHideValue=!_isHideValue;
});
},
child: Row(
children: <Widget>[
SizedBox(width: 10.0,),
Expanded(
child:Text(
"报销月份:",
style: TextStyle(fontSize: 16),
),
),
Icon(
_isHideValue ? Icons.keyboard_arrow_down : Icons.keyboard_arrow_up,
color: Colors.grey,
),
]),
)),
Offstage(
offstage: _isHideValue,
child: GridView.count(
primary: false,
shrinkWrap: true,
crossAxisCount: 3,
crossAxisSpacing: 6.0,
mainAxisSpacing: 6.0,
childAspectRatio: 2.0,
children: monthList.map((value) {
return InkWell(
onTap: () {
String month;
if (value.code == "一月") {
month='1';
} else if (value.code == "二月") {
month='2';
} else if (value.code == "三月") {
month='3';
} else if (value.code == "四月") {
month='4';
} else if (value.code == "五月") {
month='5';
} else if (value.code == "六月") {
month='6';
} else if (value.code == "七月") {
month='7';
} else if (value.code == "八月") {
month='8';
} else if (value.code == "九月") {
month='9';
} else if (value.code == "十月") {
month='10';
} else if (value.code == "十一月") {
month='11';
} else if (value.code == "十二月") {
month='12';
}
!value.check
? monthResult.add(month)
: monthResult.remove(month);
setState(() {
value.check = !value.check;
});
},
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(left: 4.0, right: 4.0),
color: value.check
? Theme.of(context).primaryColor
: Colors.grey[400],
child: Center(
child: Text(
value.code,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14, color: Colors.white),
),
),
),
Positioned(
right: 0.0,
bottom: 0.0,
child: Offstage(
offstage: !value.check,
child: Icon(
Icons.check,
color: Colors.grey,
size: 20,
),
))
],
),
);
}).toList(),
),
),
Container(
margin: EdgeInsets.only(top: 6.0),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1,
color: WSColors.mainBackgroundColor)
)
)
),
],
),
SizedBox(height: 10.0),
Text(
"报销类型:",
style: TextStyle(fontSize: 16),
),
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: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(
left: 12.0,
right: 12.0,
top: 10.0,
bottom: 10.0),
color: childNode.check
? Theme.of(context).primaryColor
: Colors.grey[400],
child: Text(childNode.code,
style: TextStyle(
fontSize: 16,
color: Colors.white,
shadows: [
BoxShadow(
color: Colors.grey,
offset: Offset(0.2, 0.2))
],
))),
Positioned(
right: 0.0,
bottom: 0.0,
child: Offstage(
offstage: !childNode.check,
child: Icon(
Icons.check,
color: Colors.grey,
size: 20,
),
))
],
),
),
onTap: () {
!childNode.check
? typeResult.add(childNode.code)
: typeResult.remove(childNode.code);
setState(() {
childNode.check = !childNode.check;
});
},
);
}).toList(),
),
SizedBox(height: 20.0),
Row(
children: <Widget>[
Expanded(
child: InkWell(
onTap: () {
monthResult.clear();
typeResult.clear();
setState(() {
monthList.forEach((element) {
element.check = false;
});
typeList.forEach((element) {
element.check = false;
});
});
},
child: Container(
height: 46,
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
"重置",
style: TextStyle(
fontSize: 14, color: Colors.white),
),
)),
),
),
SizedBox(
width: 10.0,
),
Expanded(
child: InkWell(
onTap: () {
_destroy();
},
child: Container(
height: 46,
color: Theme.of(context).primaryColor,
child: Center(
child: Text(
"确定",
style: TextStyle(
fontSize: 14, color: Colors.white),
),
)),
),
)
],
),
SizedBox(height: 20.0),
],
),
),
));
},
);
}
_destroy() async {
await LocalStorage.save(Config.MONTH_RESULT, monthResult.join(','));
await LocalStorage.save(Config.TYPE_RESULT, typeResult.join(','));
Navigator.pop(context);
}
void _loadData() {
typeList.addAll(widget.typeList);
monthList.addAll(widget.monthList);
monthList.forEach((element) {
if(element.check){
String month;
if (element.code == "一月") {
month='1';
} else if (element.code == "二月") {
month='2';
} else if (element.code == "三月") {
month='3';
} else if (element.code == "四月") {
month='4';
} else if (element.code == "五月") {
month='5';
} else if (element.code == "六月") {
month='6';
} else if (element.code == "七月") {
month='7';
} else if (element.code == "八月") {
month='8';
} else if (element.code == "九月") {
month='9';
} else if (element.code == "十月") {
month='10';
} else if (element.code == "十一月") {
month='11';
} else if (element.code == "十二月") {
month='12';
}
monthResult.add(month);
}
});
typeList.forEach((element) {
if(element.check){
typeResult.add(element.code);
}
});
}
}