在flutter项目中因为弹出框多数为底部弹框,但是也偶尔有例外。
这个时候没有flutter框架中没有合适的组件了,所以需要我们自己去实现。
具体效果截图和实现代码请往下看(该代码没有引入任何一个依赖,可以独立运行起来,所以可以放心放在框架中运行):
1、效果截图
(1)默认样式
(2) 点击菜单图标
2、代码
import 'package:flutter/material.dart';
class OrderPage extends StatefulWidget {
@override
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
bool flag=false;//控制是否显示顶部弹框
//筛选布局的高度
double selectHeight = 24;
TextEditingController trade = new TextEditingController(); //输入的交易所
TextEditingController tradePair = new TextEditingController();//输入的交易对
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
brightness: Brightness.light,
backgroundColor: Colors.white,
iconTheme: IconThemeData(color: Color(0xff000520)), //返回按钮颜色
title: Text(
"交易记录",
style: TextStyle(
fontSize: 17,
fontWeight: FontWeight.w500,
color: Color(0xff111E3E)),
),
centerTitle: true,
actions: [
GestureDetector(
onTap: (){
print("点击下拉弹框图标");
setState(() {
flag=!flag;
});
},
// child: Padding(
// padding: EdgeInsets.only(top: 5.0,right: 15),
// child: Image.asset(
// "images/celue/orderbtn@2x.png",
// width: MediaQuery.of(context).size.width*0.06,
// ),
// ),
child: Padding(
padding: EdgeInsets.only(top: 15.0,right: 15),
child: Text(
"菜单",
style: TextStyle(
fontSize: 15,
color: Colors.black
),
),
),
)
],
),
body:flag? Stack(children: <Widget>[
Column(
children: <Widget>[
Expanded(
flex: 1,
child:Container()
),
],
),
Positioned(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height - _containerPosition.dy -15, //15是筛选框距离筛选栏的距离
child: GestureDetector(
child: Container(
margin: EdgeInsets.only(top: 6),
color: Colors.black.withOpacity(0.5),
child: Column(
children: <Widget>[showSelectWidget()],
),
),
onTap: () {
setState(() {
// _selectIndex = null;
});
},
))
]):SingleChildScrollView(),
);
}
var _selectDate1= DateTime.now();
var _selectDate2= DateTime.now();
//选择日期的方法
_showDataPicker(val) async {
debugPrint('选择时间方法');
final DateTime date = await showDatePicker(
context: context,
initialDate: _selectDate1,
firstDate: DateTime(1998),
lastDate: DateTime(2030),
);
if (date == null) return;
if (val == "from") {
if(mounted){
setState(() {
_selectDate1 = date;
});
}
} else if (val == "to") {
if(mounted){
setState(() {
_selectDate2 = date;
});
}
}
}
//将时间转化为字符串类型
showDate(time){
return time.toString().split(" ")[0];
}
/// 位置信息
Offset _containerPosition = Offset(0, 0);
List year = List()
..add({"txt": '全部', "select": true})
..add({"txt": '买入', "select": false})
..add({"txt": '卖出', "select": false});
var yearWidget = List();
///订单状态
List _getYearWidgetList() {
yearWidget.clear();
yearWidget.addAll(getNewItemList(year));
return yearWidget;
}
changeType(index, List itemList) {
setState(() {
itemList[index]["select"] = !itemList[index]["select"];
for (int i = 0; i < itemList.length; i++) {
if (index != i) {
itemList[i]["select"] = false;
}
}
});
}
List getNewItemList(List itemList) {
List list = List();
itemList.asMap().forEach((i, item) =>{
list.add(GestureDetector(
onTap: (){
setState(() {
changeType(i, itemList);
print("当前的订单状态: ${item["txt"]}");
});
},
child: Container(
width: MediaQuery.of(context).size.width*0.28,
height: MediaQuery.of(context).size.height*0.06,
decoration: BoxDecoration(
color: itemList[i]["select"] ? Color(0xFF2EBEF3) : Color(0xFFE8EEF1),
borderRadius: BorderRadius.all(Radius.circular(8))),
child: Center(
child: Text(itemList[i]["txt"],
style: TextStyle(
color: itemList[i]["select"] ? Color(0xFFFFFFFF) : Color(0xFF333333))),
),
),
))
});
return list;
}
_reSet(){
tradePair.text="";
trade.text="";
year = List()
..add({"txt": '全部', "select": true})
..add({"txt": '买入', "select": false})
..add({"txt": '卖出', "select": false});
yearWidget = List();
_selectDate1= DateTime.now();
_selectDate2= DateTime.now();
}
///显示筛选Widget
Widget showSelectWidget() {
return GestureDetector(
child: Container(
color: Colors.white,
child: SizedBox(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 15, top: 25, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"订单状态",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 14
),
),
Container(
margin: EdgeInsets.only(
top: 12,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[..._getYearWidgetList()],
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 15, top: 25, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"交易所",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 14
),
),
Container(
margin: EdgeInsets.only(
top: 12,
),
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.5,
height: MediaQuery.of(context).size.height*0.06,
decoration: BoxDecoration(
color: Color(0xFFE8EEF1),
borderRadius: BorderRadius.circular(3.0),
),
child: TextField(
controller: trade,
decoration: InputDecoration(
border: InputBorder.none,
//输入框修饰
contentPadding: EdgeInsets.only(left: 5.0,bottom: 5.0),
hintText:"请输入交易所",
hintStyle: TextStyle(
fontSize: 14,
),
labelStyle: TextStyle(
fontSize: 14,
color: Color(0xff111E3E),
fontWeight: FontWeight.bold
), //设置提示文字样式
),
),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 15, top: 25, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"交易币对查询",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 14
),
),
Container(
margin: EdgeInsets.only(
top: 12,
),
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.5,
height: MediaQuery.of(context).size.height*0.06,
decoration: BoxDecoration(
color: Color(0xFFE8EEF1),
borderRadius: BorderRadius.circular(3.0),
),
child: TextField(
controller: tradePair,
decoration: InputDecoration(
border: InputBorder.none,
//输入框修饰
contentPadding: EdgeInsets.only(left: 5.0,bottom: 5.0),
hintText:"请输入交易对",
hintStyle: TextStyle(
fontSize: 14,
),
labelStyle: TextStyle(
fontSize: 14,
color: Color(0xff111E3E),
fontWeight: FontWeight.bold
), //设置提示文字样式
),
),
),
)
],
),
),
Container(
margin: EdgeInsets.only(left: 15, top: 5, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"如:查询BTC/USDT,请填写btcusdt",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 12
),
),
],
),
),
Container(
margin: EdgeInsets.only(left: 15, top: 25, right: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"时间",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 14
),
),
Container(
margin: EdgeInsets.only(
top: 12,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
GestureDetector(
behavior:HitTestBehavior.opaque,
onTap: (){
_showDataPicker("from");
},
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.36,
height: MediaQuery.of(context).size.height*0.06,
decoration: BoxDecoration(
color: Color(0xFFE8EEF1),
borderRadius: BorderRadius.circular(3.0),
),
child: Text(
"${showDate(_selectDate1)}",
style: TextStyle(
color: Color(0xFF111E3E),
fontSize: 14,
fontWeight: FontWeight.bold
),
),
),
),
Container(
child: Text(
"至",
style: TextStyle(
color: Color(0xFFBEBFC4),
fontSize: 14,
fontWeight: FontWeight.bold
),
),
),
GestureDetector(
onTap: (){
_showDataPicker("to");
},
child: Container(
alignment: Alignment.center,
width: MediaQuery.of(context).size.width*0.36,
height: MediaQuery.of(context).size.height*0.06,
decoration: BoxDecoration(
color: Color(0xFFE8EEF1),
borderRadius: BorderRadius.circular(3.0),
),
child: Text(
"${showDate(_selectDate2)}",
style: TextStyle(
color: Color(0xFF111E3E),
fontSize: 14,
fontWeight: FontWeight.bold
),
),
),
)
],
),
)
],
),
),
Container(
height: 50,
margin: EdgeInsets.only(top: 45,left: 15,right: 15,bottom: 15),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Flexible(
child: GestureDetector(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Color(0xFF2EBEF3),
),
height: 50,
width: MediaQuery.of(context).size.width*0.4,
child: Center(
child: Text(
"重置",
style: TextStyle(
fontSize: 16,
color: Colors.white
),
),
),
),
onTap: () {
setState(() {
_reSet();
});
},
),
flex: 1,
),
Flexible(
child: GestureDetector(
child: Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10.0),
color: Color(0xFF2EBEF3),
),
width: MediaQuery.of(context).size.width*0.4,
child: Center(
child: Text(
"确认",
style: TextStyle(
fontSize: 16,
color: Colors.white
),
),
),
),
onTap: () {
setState(() {
flag=false;
});
},
),
flex: 1,
),
],
),
)
],
),
),
),
onTap: () {},
);
}
}