hyzp_ybqx-Commit001:代码刚转换好,编译通过

This commit is contained in:
WinUser01
2021-12-09 20:24:36 +08:00
commit 8c74b14e5c
800 changed files with 66912 additions and 0 deletions
+144
View File
@@ -0,0 +1,144 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../../widget/JdText.dart';
import '../../widget/JdButton.dart';
import 'package:city_pickers/city_pickers.dart';
import '../../services/UserServices.dart';
import '../../services/SignServices.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class AddressAddPage extends StatefulWidget {
AddressAddPage({Key key}) : super(key: key);
_AddressAddPageState createState() => _AddressAddPageState();
}
class _AddressAddPageState extends State<AddressAddPage> {
String area='';
String name='';
String phone='';
String address='';
//监听页面销毁的事件
dispose(){
super.dispose();
eventBus.fire(new AddressEvent('增加成功...'));
eventBus.fire(new CheckOutEvent('改收货地址成功...'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("增加收货地址"),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
SizedBox(height: 20),
JdText(
text: "收货人姓名",
onChanged: (value){
this.name=value;
},
),
SizedBox(height: 10),
JdText(
text: "收货人电话",
onChanged: (value){
this.phone=value;
},
),
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(left: 5),
height: ScreenUtil().setHeight(68),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 1, color: Colors.black12))),
child: InkWell(
child: Row(
children: <Widget>[
Icon(Icons.add_location),
this.area.length>0?Text('${this.area}', style: TextStyle(color: Colors.black54)):Text('省/市/区', style: TextStyle(color: Colors.black54))
],
),
onTap: () async{
Result result = await CityPickers.showCityPicker(
context: context,
cancelWidget:
Text("取消", style: TextStyle(color: Colors.blue)),
confirmWidget:
Text("确定", style: TextStyle(color: Colors.blue))
);
print(result);
setState(() {
this.area= "${result.provinceName}/${result.cityName}/${result.areaName}";
});
},
),
),
SizedBox(height: 10),
JdText(
text: "详细地址",
maxLines: 4,
height: 200,
onChanged: (value){
this.address="${this.area} ${value}";
},
),
SizedBox(height: 10),
SizedBox(height: 40),
JdButton(text: "增加", color: Colors.red,onTop: () async{
List userinfo=await UserServices.getUserInfo();
print(userinfo);
// print('1234');
var tempJson={
"uid":userinfo[0]["_id"],
"name":this.name,
"phone":this.phone,
"address":this.address,
"salt":userinfo[0]["salt"]
};
var sign=SignServices.getSign(tempJson);
// print(sign);
var api = '${Config.domain}api/addAddress';
var result = await Dio().post(api,data:{
"uid":userinfo[0]["_id"],
"name":this.name,
"phone":this.phone,
"address":this.address,
"sign":sign
});
// if(result.data["success"]){
// }
Navigator.pop(context);
})
],
),
));
}
}
+155
View File
@@ -0,0 +1,155 @@
import 'package:flutter/material.dart';
import '../../widget/JdText.dart';
import '../../widget/JdButton.dart';
import 'package:city_pickers/city_pickers.dart';
import '../../services/UserServices.dart';
import '../../services/SignServices.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class AddressEditPage extends StatefulWidget {
Map arguments;
AddressEditPage({Key key,this.arguments}) : super(key: key);
_AddressEditPageState createState() => _AddressEditPageState();
}
class _AddressEditPageState extends State<AddressEditPage> {
String area='';
TextEditingController nameController=new TextEditingController();
TextEditingController phoneController=new TextEditingController();
TextEditingController addressController=new TextEditingController();
@override
void initState() {
// TODO: implement initState
super.initState();
// print(widget.arguments);
nameController.text=widget.arguments['name'];
phoneController.text=widget.arguments['phone'];
addressController.text=widget.arguments['address'];
}
//监听页面销毁的事件
dispose(){
super.dispose();
eventBus.fire(new AddressEvent('增加成功...'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("修改收货地址"),
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
SizedBox(height: 20),
JdText(
controller: nameController,
text: "收货人姓名",
onChanged: (value){
nameController.text=value;
},
),
SizedBox(height: 10),
JdText(
controller: phoneController,
text: "收货人电话",
onChanged: (value){
phoneController.text=value;
},
),
SizedBox(height: 10),
Container(
padding: EdgeInsets.only(left: 5),
height: ScreenUtil().setHeight(68),
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(width: 1, color: Colors.black12))),
child: InkWell(
child: Row(
children: <Widget>[
Icon(Icons.add_location),
this.area.length>0?Text('${this.area}', style: TextStyle(color: Colors.black54)):Text('省/市/区', style: TextStyle(color: Colors.black54))
],
),
onTap: () async{
Result result = await CityPickers.showCityPicker(
context: context,
locationCode: "130102",
cancelWidget:
Text("取消", style: TextStyle(color: Colors.blue)),
confirmWidget:
Text("确定", style: TextStyle(color: Colors.blue))
);
// print(result);
setState(() {
this.area= "${result.provinceName}/${result.cityName}/${result.areaName}";
});
},
),
),
SizedBox(height: 10),
JdText(
controller: addressController,
text: "详细地址",
maxLines: 4,
height: 200,
onChanged: (value){
addressController.text=value;
},
),
SizedBox(height: 10),
SizedBox(height: 40),
JdButton(text: "修改", color: Colors.red,onTop: () async{
List userinfo=await UserServices.getUserInfo();
var tempJson={
"uid":userinfo[0]["_id"],
"id":widget.arguments["id"],
"name": nameController.text,
"phone":phoneController.text,
"address":addressController.text,
"salt":userinfo[0]["salt"]
};
var sign=SignServices.getSign(tempJson);
// print(sign);
var api = '${Config.domain}api/editAddress';
var response = await Dio().post(api,data:{
"uid":userinfo[0]["_id"],
"id":widget.arguments["id"],
"name": nameController.text,
"phone":phoneController.text,
"address":addressController.text,
"sign":sign
});
print(response);
Navigator.pop(context);
})
],
),
)
);
}
}
+256
View File
@@ -0,0 +1,256 @@
import 'package:flutter/material.dart';
import '../../services/UserServices.dart';
import '../../services/SignServices.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class AddressListPage extends StatefulWidget {
AddressListPage({Key key}) : super(key: key);
_AddressListPageState createState() => _AddressListPageState();
}
class _AddressListPageState extends State<AddressListPage> {
List addressList = [];
@override
void initState() {
super.initState();
this._getAddressList();
//监听增加收货地址的广播
eventBus.on<AddressEvent>().listen((event) {
// print(event.str);
this._getAddressList();
});
}
//监听页面销毁的事件
dispose(){
super.dispose();
eventBus.fire(new CheckOutEvent('改收货地址成功...'));
}
//获取收货地址列表
_getAddressList() async {
//请求接口
List userinfo = await UserServices.getUserInfo();
var tempJson = {"uid": userinfo[0]['_id'], "salt": userinfo[0]["salt"]};
var sign = SignServices.getSign(tempJson);
var api =
'${Config.domain}api/addressList?uid=${userinfo[0]['_id']}&sign=${sign}';
var response = await Dio().get(api);
// print(response.data["result"]);
setState(() {
this.addressList = response.data["result"];
});
}
//修改默认收货地址
_changeDefaultAddress(id) async{
List userinfo = await UserServices.getUserInfo();
var tempJson = {"uid": userinfo[0]['_id'], "id":id,"salt": userinfo[0]["salt"]};
var sign = SignServices.getSign(tempJson);
var api =
'${Config.domain}api/changeDefaultAddress';
var response = await Dio().post(api,data:{
"uid": userinfo[0]['_id'],
"id":id,
"sign":sign
});
Navigator.pop(context);
}
//删除收货地址
_delAddress(id) async{
List userinfo=await UserServices.getUserInfo();
var tempJson={
"uid":userinfo[0]["_id"],
"id":id,
"salt":userinfo[0]["salt"]
};
var sign=SignServices.getSign(tempJson);
var api = '${Config.domain}api/deleteAddress';
var response = await Dio().post(api,data:{
"uid":userinfo[0]["_id"],
"id":id,
"sign":sign
});
this._getAddressList(); //删除收货地址完成后重新获取列表
}
//弹出框
_showDelAlertDialog(id) async{
var result= await showDialog(
barrierDismissible:false, //表示点击灰色背景的时候是否消失弹出框
context:context,
builder: (context){
return AlertDialog(
title: Text("提示信息!"),
content:Text("您确定要删除吗?") ,
actions: <Widget>[
FlatButton(
child: Text("取消"),
onPressed: (){
Navigator.pop(context);
},
),
FlatButton(
child: Text("确定"),
onPressed: () async{
//执行删除操作
this._delAddress(id);
Navigator.pop(context);
},
)
],
);
}
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("收货地址列表"),
),
body: Container(
child: Stack(
children: <Widget>[
ListView.builder(
itemCount: this.addressList.length,
itemBuilder: (context, index) {
if (this.addressList[index]["default_address"] == 1) {
return Column(
children: <Widget>[
SizedBox(height: 20),
ListTile(
leading: Icon(Icons.check, color: Colors.red),
title: InkWell(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"${this.addressList[index]["name"]} ${this.addressList[index]["phone"]}"),
SizedBox(height: 10),
Text("${this.addressList[index]["address"]}"),
]),
onTap: (){
this._changeDefaultAddress(this.addressList[index]["_id"]);
},
onLongPress: (){
this._showDelAlertDialog(this.addressList[index]["_id"]);
},
),
trailing: IconButton(
icon:Icon(Icons.edit, color: Colors.blue),
onPressed: (){
Navigator.pushNamed(context, '/addressEdit',arguments: {
"id":this.addressList[index]["_id"],
"name":this.addressList[index]["name"],
"phone":this.addressList[index]["phone"],
"address":this.addressList[index]["address"],
});
},
),
),
Divider(height: 20),
],
);
} else {
return Column(
children: <Widget>[
SizedBox(height: 20),
ListTile(
title:InkWell(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"${this.addressList[index]["name"]} ${this.addressList[index]["phone"]}"),
SizedBox(height: 10),
Text("${this.addressList[index]["address"]}"),
]),
onTap: (){
this._changeDefaultAddress(this.addressList[index]["_id"]);
},
onLongPress: (){
this._showDelAlertDialog(this.addressList[index]["_id"]);
},
),
trailing: IconButton(
icon:Icon(Icons.edit, color: Colors.blue),
onPressed: (){
Navigator.pushNamed(context, '/addressEdit',arguments: {
"id":this.addressList[index]["_id"],
"name":this.addressList[index]["name"],
"phone":this.addressList[index]["phone"],
"address":this.addressList[index]["address"],
});
},
),
),
Divider(height: 20),
],
);
}
},
),
Positioned(
bottom: 0,
width: ScreenUtil().setWidth(750),
height: ScreenUtil().setHeight(88),
child: Container(
padding: EdgeInsets.all(5),
width: ScreenUtil().setWidth(750),
height: ScreenUtil().setHeight(88),
decoration: BoxDecoration(
color: Colors.red,
border: Border(
top: BorderSide(width: 1, color: Colors.black26))),
child: InkWell(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.add, color: Colors.white),
Text("增加收货地址", style: TextStyle(color: Colors.white))
],
),
onTap: () {
Navigator.pushNamed(context, '/addressAdd');
},
),
),
)
],
),
));
}
}
+151
View File
@@ -0,0 +1,151 @@
import 'package:flutter/material.dart';
import '../../services/EventBus.dart';
import 'package:camera/camera.dart';
import '../../components/commonFun.dart';
import 'dart:io';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class FaceLogin extends StatefulWidget {
FaceLogin({this.arguments, Key key}) : super(key: key);
var arguments;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<FaceLogin> {
Future<void> camerasInit() async {
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
print(cameras.toString());
} on CameraException catch (e) {
//logError(e.code, e.description);
}
}
@override
void initState() {
super.initState();
camerasInit();
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// centerTitle: true,
// title: Text('人脸验证登录'),
// ),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
),
),
//SizedBox(height: 30),
Center(
child: Container(
//margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(800),
width: ScreenUtil().setWidth(800),
child: FlatButton(
onPressed: () {
Navigator.pushNamed(context, '/faceLogin_take_pictuer', arguments: 'FaceLogin');
},
//已经为图片header1.png添加圆形边框
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(
child: Image.asset('assets/images/header1.png', fit: BoxFit.cover),
),
),
Align(
alignment: Alignment.center,
child: Container(
alignment: Alignment(0, 0),
//192像素的图片显示出来为202像素,200 = 192 + 8
height: 200,
width: 200,
decoration: BoxDecoration(
//color: Colors.black,
shape: BoxShape.circle,
border: Border.all(color: Color.fromRGBO(88, 126, 211, 1), width: 5.0),
// borderRadius: BorderRadius.all(
// Radius.circular(400),
// ),
),
),
),
],
),
),
),
),
SizedBox(
height: 20,
),
// Container(
// alignment: Alignment(0, 0),
// width: 200,
// height: 230,
// decoration: BoxDecoration(
// border: Border.all(color: Colors.orange, width: 1.0),
// ),
// child: _getImage(widget.arguments),
// ),
],
),
),
);
}
//定义一个组件显示图片
Widget _getImage(String filePath) {
if (null == filePath) {
return Text("请选择图片...");
}
File _image = File(filePath);
//return Image.file(_image);
int imageWidth;
int imageHeight;
// 预先获取图片信息
Image image = Image.file(File.fromUri(Uri.parse(filePath)));
image.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo info, bool _) {
imageWidth = info.image.width;
imageHeight = info.image.height;
}));
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//480*720
Text('宽高:${imageWidth}x${imageHeight}', style: TextStyle(fontSize: 17.0)),
Container(
width: imageWidth / 4,
height: imageHeight / 4,
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage(filePath), fit: BoxFit.cover),
),
)
],
);
}
}
+239
View File
@@ -0,0 +1,239 @@
import 'package:flutter/material.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import 'package:hyzp_ybqx/widget/JdButton.dart';
import '../../services/EventBus.dart';
import 'package:camera/camera.dart';
import '../../components/commonFun.dart';
import 'dart:io';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class FaceLogin2 extends StatefulWidget {
FaceLogin2({this.arguments, Key key}) : super(key: key);
var arguments;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<FaceLogin2> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
Future<void> camerasInit() async {
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
print(cameras.toString());
} on CameraException catch (e) {
//logError(e.code, e.description);
}
}
@override
void initState() {
super.initState();
camerasInit();
//监听统计数据改变事件
eventBus.on<StatisDataUpdate>().listen((event) {
print(event.str);
updateMayLogin();
});
}
//处理延迟登录
updateMayLogin() {
//判断从网络获取三种统计数据是否完成
// if (listZptjStatisAlone.length >= dwSum &&
// listTodayShtj.length >= dwSum &&
// listClltjStatisAlone.length >= dwSum) {
// bMayLogin = true;
// }
if (listAllStatisData.length >= dwSum) {
bMayLogin = true;
try_setState();
}
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
double _heigth = 340;
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// centerTitle: true,
// title: Text('人脸验证登录'),
// ),
body: Container(
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(60),
right: ScreenUtil().setWidth(60),
top: ScreenUtil().setWidth(58)),
child: ListView(
children: <Widget>[
InkWell(
child: Center(
child: Container(
//margin: EdgeInsets.only(top: ScreenUtil().setHeight(40)),
height: ScreenUtil().setHeight(_heigth), //这样在不同的手机上会变形
width: ScreenUtil().setWidth(_heigth),
// height: _heigth,
// width: _heigth,
color: Colors.black12,
child: Stack(
children: [
Align(
alignment: Alignment.center,
child: Image.asset('assets/images/图层 5.png', fit: BoxFit.cover),
),
Align(
alignment: Alignment.center,
child: Column(
children: [
SizedBox(height: ScreenUtil().setHeight(_heigth / 3)),
Container(
height: ScreenUtil().setHeight(6),
color: Color.fromRGBO(53, 136, 240, 1),
),
],
),
),
Align(
alignment: Alignment.bottomCenter,
child: Container(
height: ScreenUtil().setHeight(_heigth - _heigth / 3 - 6),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Color.fromRGBO(222, 237, 255, 1),
Color.fromRGBO(255, 255, 255, 0),
],
),
),
)),
],
),
),
),
onTap: () {
if (!bMayLogin) {
return;
}
Navigator.pushNamed(context, '/faceLogin_take_pictuer', arguments: 'FaceLogin');
},
),
SizedBox(height: ScreenUtil().setHeight(40)),
Container(
height: ScreenUtil().setWidth(130),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_getImageWidget('assets/images/形状 811.png', '正对手机'),
_getImageWidget('assets/images/形状 810.png', '光线充足'),
_getImageWidget('assets/images/形状 809.png', '放慢动作'),
],
),
),
SizedBox(height: ScreenUtil().setHeight(20)),
InkWell(
onTap: () {
if (!bMayLogin) {
return;
}
Navigator.pushNamed(context, '/faceLogin_take_pictuer', arguments: 'FaceLogin');
},
child: Container(
alignment: Alignment(0, 0),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
width: ScreenUtil().setWidth(999),
height: ScreenUtil().setHeight(126),
decoration: BoxDecoration(
color: Color.fromRGBO(23, 176, 91, 1), borderRadius: BorderRadius.circular(10)),
child: Text(
bMayLogin ? "开始检测" : "加载中 . . .",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
),
// JdButton(
// height: 126,
// //JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
// width: 999,
// text: "开始检测",
// color: Color.fromRGBO(23, 176, 91, 1),
// onTop: () {
// if (!bMayLogin) {
// return;
// }
// Navigator.pushNamed(context, '/faceLogin_take_pictuer', arguments: 'FaceLogin');
// },
// ),
],
),
),
);
}
// 定义一个图文组件
Widget _getImageWidget(String imagePath, String text) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
height: ScreenUtil().setHeight(60),
child: Image.asset(imagePath, fit: BoxFit.cover),
),
Text(text, style: TextStyle(fontSize: 14)),
],
);
}
//定义一个组件显示图片
Widget _getImage(String filePath) {
if (null == filePath) {
return Text("请选择图片...");
}
File _image = File(filePath);
//return Image.file(_image);
int imageWidth;
int imageHeight;
// 预先获取图片信息
Image image = Image.file(File.fromUri(Uri.parse(filePath)));
image.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo info, bool _) {
imageWidth = info.image.width;
imageHeight = info.image.height;
}));
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
//480*720
Text('宽高:${imageWidth}x${imageHeight}', style: TextStyle(fontSize: 17.0)),
Container(
width: imageWidth / 4,
height: imageHeight / 4,
decoration: BoxDecoration(
image: DecorationImage(image: AssetImage(filePath), fit: BoxFit.cover),
),
)
],
);
}
}
+399
View File
@@ -0,0 +1,399 @@
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:flutter_drag_scale/core/drag_scale_widget.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/customDialogFaceReg.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:image_picker/image_picker.dart';
import '../../components/commonFun.dart';
import '../../services/EventBus.dart';
class FaceReg extends StatefulWidget {
FaceReg({this.arguments, Key key}) : super(key: key);
var arguments;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<FaceReg> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
Future<void> camerasInit() async {
try {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
print(cameras.toString());
} on CameraException catch (e) {
//logError(e.code, e.description);
}
}
String imagePath = '';
Size imageSize;
String _username;
//人脸注册页面,这里建议自动填入当前登录用户名
TextEditingController _controller = TextEditingController(text: g_userInfo.username);
@override
void initState() {
camerasInit();
//监听人脸注册数据更新事件
eventBus.on<FaceRegUpdateEvent>().listen((event) async {
print(event.str);
try_setState();
});
super.initState();
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("人脸注册",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
//解决 Flutter ListView 子元素 无限宽度 的问题
Container(
alignment: Alignment.topCenter,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 20, bottom: 5, left: 0, right: 0),
height: ScreenUtil().setHeight(200),
width: ScreenUtil().setWidth(260),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SizedBox(width: 10),
Container(
padding: EdgeInsets.only(top: 16),
child: Text('用户名: ', style: TextStyle(fontSize: 18)),
),
Container(
height: ScreenUtil().setHeight(160),
width: ScreenUtil().setWidth(500),
child: TextField(
//textAlign: TextAlign.right,
textAlignVertical: TextAlignVertical.center,
maxLines: 1,
style: TextStyle(fontSize: 18),
decoration: InputDecoration(
hintText: '請輸入用户名',
//border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
enabledBorder: new UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
focusedBorder: new UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue)),
),
controller: _controller,
//利用控制器初始化文本
onChanged: (value) {
_username = value;
},
),
),
SizedBox(width: 10),
Container(
width: ScreenUtil().setWidth(220),
padding: EdgeInsets.only(top: 16),
child: FlatButton(
color: Colors.black12,
child: Text('本人', style: TextStyle(color: Colors.blue, fontSize: 18)),
onPressed: () {
_controller.text = g_userInfo.username;
},
),
),
],
),
//SizedBox(height: 30),
SizedBox(height: 10),
//480*720
Text(null == imageSize ? '' : '宽高:${imageSize.width}x${imageSize.height}',
style: TextStyle(fontSize: 18)),
SizedBox(height: 5),
Container(
alignment: Alignment(0, 0),
width: ScreenUtil().setWidth(980),
height: ScreenUtil().setHeight(760),
decoration: BoxDecoration(
border: Border.all(color: Colors.orange, width: 1.0),
borderRadius: BorderRadius.circular(5),
),
child: _getImage(imagePath),
),
SizedBox(height: 25),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
getBtnSizeX(
width: 90,
text: "拍照",
onPressedFun: () {
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
_username = _controller.text;
Navigator.pushNamed(context, '/faceReg_take_pictuer',
arguments: 'FaceReg')
.then((_imagePath) {
_controller.text = _username;
imagePath = _imagePath as String;
if (imagePath.isNotEmpty) {
print('imagePath = $imagePath');
//imageSize = Size(480, 720);
getImageSize(imagePath);
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新'));
}
});
}),
getBtnSizeX(
width: 90,
text: "选择图片",
onPressedFun: () {
//Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
_getImageGallery();
}),
getBtnSizeX(
width: 90,
text: "人脸注册",
onPressedFun: (_controller.text.isEmpty && imagePath.isEmpty)
? null
: () {
//人脸注册,username 用户名,filePath 人脸图片路径
if (_controller.text.isNotEmpty && imagePath.isNotEmpty) {
print('等待人脸注册或更新确认');
Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogFaceReg(
title: '人脸注册或更新确认',
username: _username,
imagePath: imagePath,
imageSize: imageSize,
),
),
)
.then((ret) async {
print('value = $ret');
if (ret) {
print('用户已确认,开始处理人脸注册或更新!');
faceRegFun(
username: _username,
filePath: imagePath,
context: context);
} else {
print('用户取消了人脸注册或更新');
}
});
} else if (_controller.text.isEmpty) {
Fluttertoast.showToast(
msg: "用户名不能为空!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (imagePath.isEmpty) {
Fluttertoast.showToast(
msg: "请选择用户人脸图片!",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}),
],
),
// RaisedButton(
// child: Text('人脸登录'),
// onPressed: () {
// Navigator.pushNamed(context, '/faceReg_take_pictuer', arguments: 'FaceLogin');
// }),
SizedBox(height: 10),
],
),
),
],
)),
);
}
//从相册选取图片
Future _getImageGallery() async {
final imagePicker = ImagePicker();
_username = _controller.text;
//final pickedFile = await imagePicker.getImage(source: ImageSource.gallery, maxWidth: 400);
imagePicker.getImage(source: ImageSource.gallery, maxWidth: 480).then((pickedFile) {
if (pickedFile != null) {
print('pickedFile = ${pickedFile.path}');
imagePath = pickedFile.path;
getImageSize(imagePath);
} else {
print('No image selected.');
}
_controller.text = _username;
});
}
//定义一个组件显示图片
_getImage(String filePath) {
print('filePath = $filePath');
if (null == imageSize || filePath.isEmpty) {
return Text("注意:\n1、请输入“已注册”的用户名;\n2、请选择包含“用户人脸”的图片;\n3、两样都选好后再进行注册,不然可能失败!");
}
double _width = ScreenUtil().setWidth(980);
double _heigth = _width * (imageSize.height / imageSize.width);
final _image = Image.file(File(filePath));
// 预先获取图片信息
return SingleChildScrollView(
//滑动的方向 Axis.vertical为垂直方向滑动,Axis.horizontal 为水平方向
scrollDirection: Axis.vertical,
//true 滑动到底部
reverse: false,
padding: EdgeInsets.all(0.0),
//滑动到底部回弹效果
physics: BouncingScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: _width,
height: _heigth,
// child: PinchZoomImage( //不好用
// //image: Image.network('https://i.imgur.com/tKg0XEb.jpg'),
// image: _image,
// zoomedBackgroundColor: Color.fromRGBO(240, 240, 240, 1.0),
// hideStatusBarWhileZooming: true,
// onZoomStart: () {
// print('Zoom started');
// },
// onZoomEnd: () {
// print('Zoom finished');
// },
// ),
//DragScaleContainer 插件只能放大,不能缩小到比原始尺寸小
child: DragScaleContainer(doubleTapStillScale: true, child: _image
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
//child: _image,
//一个大坑:用 AssetImage(filePath) 方式,首次加载拍照返回的照片,始终报错,刷新后则能够正常加载。
// 用 Container 的 child 方式解决
// decoration: BoxDecoration(
// image: DecorationImage(image: AssetImage(filePath), fit: BoxFit.cover),
// ),
)
],
),
);
}
// 预先获取图片信息
Future getImageSize(String filePath) async {
Image image = Image.file(File.fromUri(Uri.parse(filePath)));
image.image
.resolve(new ImageConfiguration())
.addListener(new ImageStreamListener((ImageInfo info, bool _) {
imageSize = Size(
info.image.width.toDouble(),
info.image.height.toDouble(),
);
print('imageSize = $imageSize');
//必须延迟刷新,否则启动App后,第一次进行拍照返回会抛异常,无法显示返回的照片
//启动App后,第一次进行拍照返回,在 AS Terminal 按 R 刷新可以显示图片。
//暂存,后续解决
try_setState();
// Future.delayed(const Duration(milliseconds: 3000), () {
// //try_setState();
//eventBus.fire(FaceRegUpdateEvent('人脸注册数据已更新')); //这样刷新有效
// });
}));
}
}
+153
View File
@@ -0,0 +1,153 @@
import 'package:flutter/material.dart';
import '../../components/commonFun.dart';
import '../../widget/JdText.dart';
import '../../widget/JdButton.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../services/Storage.dart';
import 'dart:convert';
import '../../components/EncryptUtil.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ForgotPassword extends StatefulWidget {
ForgotPassword({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<ForgotPassword> {
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
doLogin() async {
//临时跳转
Navigator.pushNamed(context, '/', arguments: g_iIndex);
return;
RegExp reg = new RegExp(r"^1\d{10}$");
if (!reg.hasMatch(g_userInfo.username)) {
Fluttertoast.showToast(
msg: '手机号格式不对',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (g_userInfo.password.length < 6) {
Fluttertoast.showToast(
msg: '密码不正确',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else {
var api = '${Config.domain}api/doLogin';
var response = await Dio().post(api, data: {
"username": g_userInfo.username,
"password": g_userInfo.password
});
if (response.data["success"]) {
print(response.data);
//保存用户信息
Storage.setString('userInfo', json.encode(response.data["userinfo"]));
Navigator.pop(context);
} else {
Fluttertoast.showToast(
msg: '${response.data["message"]}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("找回密码"),
centerTitle: true,
),
body: Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
// child: Image.network(
// 'https://www.itying.com/images/flutter/list5.jpg',
// fit: BoxFit.cover),
),
),
SizedBox(height: 30),
JdText(
height: ScreenUtil().setHeight(300),
title: '账号:',
text: "请输入账号(手机号)",
onChanged: (String value) {
// print(value);
g_userInfo.username = value;
},
endBtn: 'ClearBtn',
),
SizedBox(height: 10),
JdText(
height: ScreenUtil().setHeight(300),
title: '验证码:',
text: "请输入短信验证码",
password: true,
onChanged: (String value) {
// print(value);
g_userInfo.password = value;
},
endBtn: 'OutlineButton',
),
SizedBox(height: 10),
JdText(
height: ScreenUtil().setHeight(300),
title: '新密码:',
text: "请输入6-12位新密码",
password: true,
onChanged: (String value) {
// print(value);
g_userInfo.password = value;
},
endBtn: 'ShowHiddenBtn',
),
SizedBox(height: 10),
JdText(
height: ScreenUtil().setHeight(300),
title: '新密码:',
text: "请再次输入6-12位新密码",
password: true,
onChanged: (String value) {
// print(value);
g_userInfo.password = value;
},
endBtn: 'ShowHiddenBtn',
),
SizedBox(height: 40),
JdButton(
height: ScreenUtil().setHeight(350),
text: "确认",
color: Colors.blueAccent,
onTop: doLogin,
)
],
),
),
);
}
}
+279
View File
@@ -0,0 +1,279 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hyzp_ybqx/components/UserAuthority.dart';
import '../../components/commonFun.dart';
import '../../widget/JdText.dart';
import '../../widget/JdButton.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../services/Storage.dart';
import 'dart:convert';
import '../../components/EncryptUtil.dart';
import '../../services/EventBus.dart';
import '../../config/service_url.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class LoginByName extends StatefulWidget {
LoginByName({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginByName> {
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
bool bRemmberPW = false;
@override
void initState() {
super.initState();
// g_userInfo.username = 'the_user_03';
// g_userInfo.password = '123456';
// g_userInfo.password = 'ybhb1234';
g_userInfo.username = '';
g_userInfo.password = '';
doInit();
}
doInit() async {
bRemmberPW = await Storage.getBool('bRemmberPW');
bRemmberPW = (null == bRemmberPW) ? false : bRemmberPW;
print('bRemmberPW = $bRemmberPW');
if (bRemmberPW) {
//取出后需解密
g_userInfo.username = await Storage.getString('username');
g_userInfo.username = EncryptUtil.aesDecode(g_userInfo.username);
g_userInfo.password = await Storage.getString('password');
g_userInfo.password = EncryptUtil.aesDecode(g_userInfo.password);
}
setState(() {});
}
doLogin() async {
//测试用,临时绕过登录处理
// Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
// return;
if (bRemmberPW) {
Storage.setBool('bRemmberPW', bRemmberPW);
//加密保存
Storage.setString('username', EncryptUtil.aesEncode(g_userInfo.username));
Storage.setString('password', EncryptUtil.aesEncode(g_userInfo.password));
} else {
Storage.remove('username');
Storage.remove('password');
}
var api = ServicePath.loginUrl;
print(api);
try {
print('开始处理登录请求...');
print('username = ${g_userInfo.username}');
print('password = ${g_userInfo.password}');
Response response;
Dio dio = Dio();
String random = RandomBit(6); //flutter (dart)生成N位随机数
response = await dio.post(api, data: {
"username": g_userInfo.username,
"password": g_userInfo.password,
"sign": GenerateMd5(APPkey + random),
"random": random,
});
print('response = ${response.toString()}');
//I/flutter ( 5242): {"ret":200,"data":{"is_login":true,"user_id":3,"token":"32EE57A0109A3D1D6590CFD3DEBA71820F77AB654093C1DE750347C88D1A41CF"},"msg":""}
if (response.statusCode == 200) {
// Storage.setString('userInfo', json.encode(response.data["userinfo"]));
// //Navigator.pop(context);
// Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
//print('response.data["data"]["is_login"] = ${response.data["data"]["is_login"]}');
//I/flutter ( 5242): response.data["data"]["is_login"] = true
//{
// "ret": 200,
// "data": {
// "is_login": true,
// "user_id": 1,
// "token": "B93EC91FA2FE293B7077162D4527FC4BB228CD6C0A4F24A882B9A8BBE6C3FB47"
// },
// "msg": ""
// }
print('response = ${response}');
//response = {"ret":406,"data":{},"msg":"非法请求:签名错误"}
if (true == response.data["data"]["is_login"]) {
print('登录成功');
print('response.data = ${response.data}');
//保存用户信息
Storage.setString('userInfo', json.encode(response.data["data"]));
g_userInfo.setUserInfo(theMapUserInfoRet: await getMapFromJson(response.data));
//获取用户所属分组和相应权限
getUserGroupAll().then((value) {
//Navigator.pop(context);
Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
});
} else {
print('登录失败:${response.data["data"]}');
Fluttertoast.showToast(
msg: '登录失败:用户名或密码不正确。}',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
print('登录失败:${response.data["data"]}');
}
print('登录过程正常完成');
} else {
throw Exception('后端接口出现异常,请检测代码和服务器情况.........');
}
} catch (e) {
print('登录过程异常...');
print('ERROR:======>${e}');
Fluttertoast.showToast(
msg: 'ERROR:======>${e}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
return;
}
@override
Widget build(BuildContext context) {
//FocusScope.of(context).requestFocus(FocusNode());
//FocusScope.of(context).unfocus();
return Scaffold(
body: Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
// child: Image.network(
// 'https://www.itying.com/images/flutter/list5.jpg',
// fit: BoxFit.cover),
),
),
SizedBox(height: 30),
JdText(
height: ScreenUtil().setHeight(300),
title: '账号:',
text: "请输入账号",
onChanged: (String value) {
// print(value);
g_userInfo.username = value;
},
endBtn: 'ClearBtn',
controller: TextEditingController(text: g_userInfo.username),
),
SizedBox(height: 10),
JdText(
height: ScreenUtil().setHeight(300),
title: '密码:',
text: "请输入密码",
password: true,
onChanged: (String value) {
// print(value);
g_userInfo.password = value;
},
endBtn: 'ShowHiddenBtn',
controller: TextEditingController(text: g_userInfo.password),
),
SizedBox(height: 10),
Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: Stack(
children: <Widget>[
// Align(
// alignment: Alignment.centerLeft,
// child: InkWell(
// onTap: () {
// Navigator.pushNamed(context, '/forgotPassword');
// },
// child: Text('忘记密码'),
// ),
// ),
Align(
alignment: Alignment.topRight,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/registerFirst');
},
//child: Text('记住密码'),
child: Container(
alignment: Alignment(1, -1),
width: 150,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('记住密码:'),
Container(
alignment: Alignment(1, -1),
height: 22,
width: 22,
child: Checkbox(
value: bRemmberPW,
activeColor: Colors.blue,
onChanged: (bool val) {
this.setState(() {
bRemmberPW = !bRemmberPW;
});
Storage.setBool('bRemmberPW', bRemmberPW);
},
),
),
],
),
),
),
),
// Align(
// alignment: Alignment.centerRight,
// child: InkWell(
// onTap: () {
// Navigator.pushNamed(context, '/registerFirst');
// },
// child: Text(
// '新用户注册',
// style: TextStyle(
// // 创建 paint 对象,设置 color 属性为想要的颜色
// background: Paint()..color = Color.fromRGBO(218, 218, 218, 1)),
// ),
// ),
// ),
],
),
),
SizedBox(height: 20),
JdButton(
height: ScreenUtil().setHeight(350),
text: "登录",
color: Colors.blueAccent,
onTop: doLogin,
)
],
),
),
);
}
}
+328
View File
@@ -0,0 +1,328 @@
import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/UserAuthority.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import '../../components/EncryptUtil.dart';
import '../../components/commonFun.dart';
import '../../config/Config.dart';
import '../../config/service_url.dart';
import '../../services/EventBus.dart';
import '../../services/Storage.dart';
import '../../widget/JdButton.dart';
import '../../widget/JdText.dart';
class LoginByName2 extends StatefulWidget {
LoginByName2({Key key, this.height}) : super(key: key);
double height;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginByName2> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
bool bRemmberPW = false;
@override
void initState() {
super.initState();
// g_userInfo.username = 'the_user_03';
// g_userInfo.password = '123456';
// g_userInfo.password = 'ybhb1234';
g_userInfo.username = '';
g_userInfo.password = '';
doInit();
//监听统计数据改变事件
eventBus.on<StatisDataUpdate>().listen((event) {
print(event.str);
updateMayLogin();
});
}
//处理延迟登录
updateMayLogin() {
//判断从网络获取三种统计数据是否完成
// if (listZptjStatisAlone.length >= dwSum &&
// listTodayShtj.length >= dwSum &&
// listClltjStatisAlone.length >= dwSum) {
// bMayLogin = true;
// }
if (listAllStatisData.length >= dwSum) {
bMayLogin = true;
}
if (bMayLogin && bLoginVerify) {
//重新初始化处理延时登录的变量
// bMayLogin = false;
// bPreLoading = false;
// bLoginVerify = false; //处理延时登录,判断用户名登录是否验证通过
Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
// Future.delayed(const Duration(milliseconds: 1000), () {
// });
}
}
doInit() async {
bRemmberPW = await Storage.getBool('bRemmberPW');
bRemmberPW = (null == bRemmberPW) ? false : bRemmberPW;
print('bRemmberPW = $bRemmberPW');
if (bRemmberPW) {
//取出后需解密
g_userInfo.username = await Storage.getString('username');
g_userInfo.username = EncryptUtil.aesDecode(g_userInfo.username);
g_userInfo.password = await Storage.getString('password');
g_userInfo.password = EncryptUtil.aesDecode(g_userInfo.password);
}
try_setState();
}
doLogin() async {
//测试用,临时绕过登录处理
// Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
// return;
if (!bMayLogin) {
bPreLoading = true;
try_setState();
}
if (bRemmberPW) {
Storage.setBool('bRemmberPW', bRemmberPW);
//加密保存
Storage.setString('username', EncryptUtil.aesEncode(g_userInfo.username));
Storage.setString('password', EncryptUtil.aesEncode(g_userInfo.password));
} else {
Storage.remove('username');
Storage.remove('password');
}
var api = ServicePath.loginUrl;
print(api);
try {
print('开始处理登录请求...');
print('username = ${g_userInfo.username}');
print('password = ${g_userInfo.password}');
Response response;
Dio dio = Dio();
String random = RandomBit(6); //flutter (dart)生成N位随机数
response = await dio.post(api, data: {
"username": g_userInfo.username,
"password": g_userInfo.password,
"sign": GenerateMd5(APPkey + random),
"random": random,
});
print('response = ${response.toString()}');
//I/flutter ( 5242): {"ret":200,"data":{"is_login":true,"user_id":3,"token":"32EE57A0109A3D1D6590CFD3DEBA71820F77AB654093C1DE750347C88D1A41CF"},"msg":""}
if (response.statusCode == 200) {
// Storage.setString('userInfo', json.encode(response.data["userinfo"]));
// //Navigator.pop(context);
// Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
//print('response.data["data"]["is_login"] = ${response.data["data"]["is_login"]}');
//I/flutter ( 5242): response.data["data"]["is_login"] = true
//{
// "ret": 200,
// "data": {
// "is_login": true,
// "user_id": 1,
// "token": "B93EC91FA2FE293B7077162D4527FC4BB228CD6C0A4F24A882B9A8BBE6C3FB47"
// },
// "msg": ""
// }
print('response = ${response}');
//response = {"ret":406,"data":{},"msg":"非法请求:签名错误"}
if (true == response.data["data"]["is_login"]) {
print('登录成功');
print('response.data = ${response.data}');
//保存用户信息
Storage.setString('userInfo', json.encode(response.data["data"]));
g_userInfo.setUserInfo(theMapUserInfoRet: await getMapFromJson(response.data));
//获取用户所属分组和相应权限
getUserGroupAll().then((value) {
bLoginVerify = true; //处理延时登录,判断用户名登录是否验证通过
if (bMayLogin) {
// bMayLogin = false;
// bPreLoading = false;
// bLoginVerify = false; //处理延时登录,判断用户名登录是否验证通过
Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
}
});
} else {
print('登录失败:${response.data["data"]}');
bLoginVerify = false; //处理延时登录,判断用户名登录是否验证通过
bPreLoading = false;
Fluttertoast.showToast(
msg: '登录失败:用户名或密码不正确。',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
print('登录失败:${response.data["data"]}');
}
print('登录过程正常完成');
} else {
throw Exception('后端接口出现异常,请检测代码和服务器情况.........');
}
} catch (e) {
print('登录过程异常...');
print('ERROR:======>${e}');
Fluttertoast.showToast(
msg: 'ERROR:======>${e}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
return;
}
@override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false, //解决输入法键盘弹出越界问题-无效
backgroundColor: Colors.transparent,
body: Container(
height: widget.height,
child: Column(
children: [
Container(color: Colors.transparent, height: ScreenUtil().setHeight(45)),
Container(
color: Colors.white,
width: double.infinity,
height: ScreenUtil().setHeight(380),
padding: EdgeInsets.only(top: 10, bottom: 20, left: 20, right: 20),
child: Column(
children: <Widget>[
JdText(
height: 126,
//JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
title: '用户名:',
text: "请输入用户名",
onChanged: (String value) {
// print(value);
g_userInfo.username = value;
},
endBtn: 'ClearBtn',
controller: TextEditingController(text: g_userInfo.username),
),
Container(color: Colors.transparent, height: ScreenUtil().setHeight(30)),
JdText(
height: 126,
//JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
title: '密 码:',
text: "请输入密码",
password: true,
onChanged: (String value) {
g_userInfo.password = value;
},
endBtn: 'ShowHiddenBtn',
controller: TextEditingController(text: g_userInfo.password),
),
],
),
),
Container(color: Colors.transparent, height: ScreenUtil().setHeight(30)),
Container(
//color: Colors.transparent,
padding: EdgeInsets.all(ScreenUtil().setWidth(10)),
child: Row(
children: [
SizedBox(width: ScreenUtil().setWidth(45)),
InkWell(
onTap: () {
//Navigator.pushNamed(context, '/registerFirst');
this.setState(() {
bRemmberPW = !bRemmberPW;
});
Storage.setBool('bRemmberPW', bRemmberPW);
},
child: Container(
alignment: Alignment(1, -1),
//width: 150,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment(0, 0),
height: 22,
width: 22,
padding: EdgeInsets.only(top: ScreenUtil().setHeight(3)),
// child: Checkbox(
// value: bRemmberPW,
// activeColor: Colors.blue,
// onChanged: (bool val) {
// this.setState(() {
// bRemmberPW = !bRemmberPW;
// });
// Storage.setBool('bRemmberPW', bRemmberPW);
// },
// ),
child: bRemmberPW
? Icon(Icons.check_box, color: Colors.blue)
: Icon(Icons.check_box_outline_blank, color: Colors.white),
),
SizedBox(width: ScreenUtil().setWidth(15)),
Text('记住密码', style: TextStyle(fontSize: 17, color: Colors.white)),
],
),
),
),
],
),
),
SizedBox(height: ScreenUtil().setHeight(48)),
InkWell(
onTap: doLogin,
child: Container(
alignment: Alignment(0, 0),
margin: EdgeInsets.all(5),
padding: EdgeInsets.all(5),
width: ScreenUtil().setWidth(999),
height: ScreenUtil().setHeight(126),
decoration: BoxDecoration(
color: Color.fromRGBO(23, 176, 91, 1), borderRadius: BorderRadius.circular(10)),
child: Text(
bPreLoading ? "加载中 . . ." : "登 录",
style: TextStyle(color: Colors.white, fontSize: 18),
),
),
),
// JdButton(
// height: 126,
// //JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
// width: 999,
// text: "登 录",
// color: Color.fromRGBO(23, 176, 91, 1),
// onTop: doLogin,
// ),
],
),
),
);
}
}
+105
View File
@@ -0,0 +1,105 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../components/commonFun.dart';
import '../../services/Storage.dart';
import 'FaceLogin.dart';
import 'LoginByName2.dart';
// class LoginTabs extends StatelessWidget {
// // This widget is the root of your application.
// @override
// Widget build(BuildContext context) {
// //Flutter 强制竖屏
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.portraitUp, //只能纵向
// DeviceOrientation.portraitDown, //只能纵向
// ]);
//
// return MaterialApp(
// debugShowCheckedModeBanner: false,
// title: 'Flutter Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// visualDensity: VisualDensity.adaptivePlatformDensity,
// ),
// home: MyHomePage(title: 'Flutter Demo Home Page'),
// );
// }
// }
class LoginTabs extends StatefulWidget {
LoginTabs({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<LoginTabs> {
@override
void initState() {
super.initState();
//若下面文件不存在,
// /data/data/com.flutter.hyzp_ybqx/shared_prefs/FlutterSharedPreferences.xml
// value为null, 会抛出异常:
// [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): The source must not be null
// int.parse (dart:core-patch/integers_patch.dart:51:25)
Storage.getString("tabs_index").then((value) {
g_iIndex = (null == value) ? 0 : int.parse(value);
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/背景图.png"),
fit: BoxFit.cover,
),
),
child: Container(
width: double.infinity,
height: 400,
child: Container(
constraints: BoxConstraints(
minWidth: double.infinity, //最小宽度尽量取最大
maxHeight: 400 //最小高度为80
),
child: DefaultTabController(
length: 2,
child: Scaffold(
//backgroundColor: Colors.transparent,
appBar: AppBar(
//backgroundColor: Colors.transparent,
title: Text("宜宾市黑烟车电子抓拍系统"),
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () {
SystemNavigator.pop();
},
),
centerTitle: true,
bottom: TabBar(
labelColor: Colors.blueAccent,
unselectedLabelColor: Colors.black26,
tabs: <Widget>[Tab(text: "密码登录"), Tab(text: "刷脸登录")],
),
),
body: TabBarView(
//flutter tabbar禁止手势滑动-OK
physics: new NeverScrollableScrollPhysics(),
children: <Widget>[
LoginByName2(),
FaceLogin(),
],
),
),
),
),
),
);
}
}
+174
View File
@@ -0,0 +1,174 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../../components/commonFun.dart';
import 'LoginByName2.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'LoginTabsWidget.dart';
const pageData = {
"discountStatus": 2,
"subscribeStatus": "0",
"title": "限时免费",
"subTitle": "活动时间9月1日-9月30日",
"packageList": [
{"id": 23, "desc": "月度订阅", "dealPrice": 10, "originPrice": 50, "recommand": 1},
{"id": 33, "desc": "半年订阅", "dealPrice": 56, "originPrice": 280, "recommand": 0},
{"id": 56, "desc": "年度订阅", "dealPrice": 108, "originPrice": 540, "recommand": 0}
]
};
class LoginTabs2 extends StatefulWidget {
@override
createState() => new LoginTabs2State();
}
// ScreenUtil().statusBarHeight + ScreenUtil().setHeight(144) + ScreenUtil().setHeight(348)
// + ScreenUtil().setHeight(36) + height: ScreenUtil().setHeight(166) + ScreenUtil().setHeight(17)
// + ScreenUtil().setHeight(826)
class LoginTabs2State extends State<LoginTabs2> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(child: AppBar(), preferredSize: Size.fromHeight(0)),
//使用 SingleChildScrollView 包装一下,否则键盘弹出时会报错空间溢出
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: ScreenUtil().screenHeight -
ScreenUtil().statusBarHeight -
ScreenUtil().bottomBarHeight,
width: ScreenUtil().screenWidth,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage("assets/images/背景图.png"), fit: BoxFit.cover)),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
// alignment: WrapAlignment.center,
// crossAxisAlignment: WrapCrossAlignment.center,
// runSpacing: 9.0,
children: <Widget>[
Container(
height: ScreenUtil().setHeight(144),
//padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
IconButton(
onPressed: () {
//Navigator.pop(context);
SystemNavigator.pop(); //退出App
},
icon: const Icon(Icons.close, color: Colors.white),
)
],
),
),
Center(
child: Container(
margin: EdgeInsets.only(top: ScreenUtil().setHeight(0)),
width: ScreenUtil().setWidth(490), //单位px,
height: ScreenUtil().setHeight(348),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/图层 2.png', fit: BoxFit.fitHeight),
),
),
SizedBox(height: ScreenUtil().setHeight(36)),
Container(
height: ScreenUtil().setHeight(166),
margin: EdgeInsets.all(0),
child: RichText(
maxLines: 2,
textAlign: TextAlign.center,
text: TextSpan(children: [
TextSpan(
text: '宜宾黑烟车',
style: TextStyle(
fontSize: 26.0, color: Colors.white, fontWeight: FontWeight.bold)),
TextSpan(
text: '抓拍系统',
style: TextStyle(
fontSize: 26.0,
color: Color.fromRGBO(49, 216, 123, 1),
fontWeight: FontWeight.bold)),
TextSpan(
text: '\nYIBIN BLACK SMOKE CAR CAPTURE SYSTEM',
style:
TextStyle(fontSize: 11.0, color: Color.fromRGBO(101, 117, 142, 1))),
]),
),
),
SizedBox(height: ScreenUtil().setHeight(17)),
Container(
height: ScreenUtil().setHeight(945),
child: LoginTabsWidget(),
),
Container(color: Colors.transparent, height: ScreenUtil().setHeight(30)),
Container(
color: Colors.transparent,
height: ScreenUtil().setHeight(130), //不能超过133,否则有些手机会越界
child: Text(
//'© 宜宾市生态环境局\n© 四川省踏石科技有限公司 版权所有 \n服务热线:187-8467-8300',
//'© 宜宾市生态环境局\n© 四川省踏石科技有限公司',
'© 宜宾市生态环境局 四川省踏石科技 版权所有\n服务热线:187-8467-8300',
maxLines: 2,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 16.0,
color: Color.fromRGBO(106, 144, 204, 1),
fontWeight: FontWeight.bold),
),
),
//144
// 384
// 36
// 166
// 17
// 1026
// 1573
// 1768
//S7采用5.1英寸的Super AMOLED屏幕,分辨率为2560 ×1440(Quad HD),设置为1920*1080
// Wrap(
// runSpacing: 9.0,
// alignment: WrapAlignment.center,
// children: <Widget>[
// Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Text('${pageData['title']}',
// style: TextStyle(fontSize: 38.0, color: Color.fromRGBO(234, 200, 134, 1)))
// ],
// ),
// //自定义圆角
// ClipRRect(
// borderRadius: BorderRadius.circular(12.5),
// child: Container(
// height: 25.0,
// width: 190.0,
// color: Color.fromRGBO(234, 200, 134, 1),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.center,
// mainAxisAlignment: MainAxisAlignment.center,
// children: <Widget>[
// Text(
// '${pageData['subTitle']}',
// textAlign: TextAlign.center,
// style: TextStyle(color: Color.fromRGBO(113, 80, 24, 1)),
// )
// ])))
// ],
// )
],
),
),
],
),
),
);
}
}
+190
View File
@@ -0,0 +1,190 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; //import 'package:flustars/flustars.dart' as flustars; //该组件中有ScreenUtil,// 获取网络图片尺寸flustars.WidgetUtil
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/my_Tabs.dart' as my_Tabs;
import '../../components/commonFun.dart';
import '../../services/Storage.dart';
import 'FaceLogin2.dart';
import 'LoginByName2.dart';
// class LoginTabsWidget extends StatelessWidget {
// // This widget is the root of your application.
// @override
// Widget build(BuildContext context) {
// //Flutter 强制竖屏
// SystemChrome.setPreferredOrientations([
// DeviceOrientation.portraitUp, //只能纵向
// DeviceOrientation.portraitDown, //只能纵向
// ]);
//
// return MaterialApp(
// debugShowCheckedModeBanner: false,
// title: 'Flutter Demo',
// theme: ThemeData(
// primarySwatch: Colors.blue,
// visualDensity: VisualDensity.adaptivePlatformDensity,
// ),
// home: MyHomePage(title: 'Flutter Demo Home Page'),
// );
// }
// }
class LoginTabsWidget extends StatefulWidget {
LoginTabsWidget({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<LoginTabsWidget> with SingleTickerProviderStateMixin {
int loginTabs_index = 0;
//用TabController实现顶部tab切换
TabController _tabController;
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void initState() {
super.initState();
//若下面文件不存在,
// /data/data/com.flutter.hyzp_ybqx/shared_prefs/FlutterSharedPreferences.xml
// value为null, 会抛出异常:
// [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: Invalid argument(s): The source must not be null
// int.parse (dart:core-patch/integers_patch.dart:51:25)
Storage.getString("tabs_index").then((value) {
g_iIndex = (null == value) ? 0 : int.parse(value);
});
Storage.getString("LoginTabs_index").then((value) {
loginTabs_index = (null == value) ? 0 : int.parse(value);
print('loginTabs_index = ${loginTabs_index}');
//用TabController实现顶部tab切换,并设置默认 Tab。initialIndex: loginTabs_index
_tabController = TabController(vsync: this, length: 2, initialIndex: loginTabs_index);
//监听 _tabController 切换事件
_tabController.addListener(() {
Storage.setString("LoginTabs_index", _tabController.index.toString());
print('_tabController.index = ${_tabController.index}');
});
//Flutter DefaultTabController 获取/设置当前 Tab - OK
DefaultTabController.of(_scaffoldKey.currentContext).animateTo(loginTabs_index);
try_setState();
});
//监听统计数据改变事件
eventBus.on<StatisDataUpdate>().listen((event) {
print(event.str);
updateMayLogin();
});
}
//处理延迟登录
updateMayLogin() {
//判断从网络获取三种统计数据是否完成
// if (listZptjStatisAlone.length >= dwSum &&
// listTodayShtj.length >= dwSum &&
// listClltjStatisAlone.length >= dwSum) {
// bMayLogin = true;
// }
if (listAllStatisData.length >= dwSum) {
bMayLogin = true;
} else {
bMayLogin = false;
}
try_setState();
}
dispose() {
_tabController?.dispose();
super.dispose();
}
double _height = ScreenUtil().setHeight(1026);
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
height: _height,
child: DefaultTabController(
length: 2,
child: Scaffold(
key: _scaffoldKey,
backgroundColor: Colors.transparent,
appBar: PreferredSize(
preferredSize: Size.fromHeight(50), // here the desired height
child: AppBar(
backgroundColor: Colors.transparent,
bottom: TabBar(
controller: _tabController,
indicatorSize: TabBarIndicatorSize.label,
labelColor: Color.fromRGBO(49, 216, 123, 1),
unselectedLabelColor: Color.fromRGBO(118, 135, 162, 1),
//tabs: <Widget>[Tab(text: " 密码登录 "), Tab(text: " 刷脸登录 ")],
tabs: <Widget>[
my_Tabs.MyTab(
text: " 密码登录 ",
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)),
my_Tabs.MyTab(
text: " 刷脸登录 ",
style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold))
],
// tabs: <Widget>[
// Text(" 密码登录 ", style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)),
// Text(" 刷脸登录 ", style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold)),
// ],
),
),
),
body: Stack(
children: [
TabBarView(
controller: _tabController,
//flutter tabbar禁止手势滑动-OK
physics: new NeverScrollableScrollPhysics(),
children: <Widget>[
LoginByName2(height: _height),
FaceLogin2(),
],
),
// bMayLogin
// ? SizedBox.shrink()
// : Positioned(
// left: ScreenUtil().setWidth(0),
// right: ScreenUtil().setWidth(0),
// top: ScreenUtil().setHeight(297),
// child: Container(
// height: 200,
// width: 400,
// child: getMoreWidget2(
// text: '正在获取网络数据 ...',
// color: Colors.orangeAccent,
// size: 25.0,
// strokeWidth: 3.0,
// fontWeight: FontWeight.w600,
// edge: 0,
// height: 60,
// ), //显示加载中的圈圈,
// ),
// ),
],
),
),
),
);
}
}
+283
View File
@@ -0,0 +1,283 @@
import 'package:flutter/material.dart';
import '../../components/commonFun.dart';
import '../../widget/JdText.dart';
import '../../widget/JdButton.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../../services/Storage.dart';
import 'dart:convert';
import '../../components/EncryptUtil.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../config/service_url.dart';
class ModifyPassword extends StatefulWidget {
ModifyPassword({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<ModifyPassword> {
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
String oldPassword = '';
String newPassword1 = '';
String newPassword2 = '';
doModifyPw() async {
oldPassword = oldPassword.trim();
newPassword1 = newPassword1.trim();
newPassword2 = newPassword2.trim();
RegExp regNewPw = RegExp(r"^[a-zA-Z0-9\?_!@#\$\%\^&]+$");
if (g_userInfo.password.isNotEmpty && oldPassword != g_userInfo.password) {
Fluttertoast.showToast(
msg: '输入的旧密码错误!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (newPassword1 != newPassword2) {
Fluttertoast.showToast(
msg: '两次输入的新密码不一致!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (oldPassword == newPassword1) {
Fluttertoast.showToast(
msg: '新旧密码不能完全一样!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (newPassword1.length < 6 || newPassword1.length > 12) {
Fluttertoast.showToast(
msg: '新密码位数不对,应在 6-12 位之间!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (!regNewPw.hasMatch(newPassword1)) {
Fluttertoast.showToast(
msg: '新密码格式不对,应该由 6-12 位英文字母、数字和特殊符号组成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else {
doModifyPwDio().then((value) {
if (value) {
print(value);
//密码修改成,保存新密码
g_userInfo.password = newPassword1;
//加密保存新密码
Storage.setString('password', EncryptUtil.aesEncode(g_userInfo.password));
Fluttertoast.showToast(
msg: '密码修改成功!',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
);
Navigator.pop(context); // 返回上一个页面
}
});
}
}
Future doModifyPwDio() async {
var api = ServicePath.modifyPwUrl;
print(api);
bool ret = false;
try {
print('开始处理修改密码请求...');
print('username = ${g_userInfo.username}');
print('password = ${g_userInfo.password}');
Response response;
Dio dio = Dio();
String random = RandomBit(6); //flutter (dart)生成N位随机数
response = await dio.post(api, data: {
"username": g_userInfo.username,
"oldpassword": oldPassword,
"newpassword": newPassword1,
"sign": GenerateMd5(APPkey + random),
"random": random,
});
print('response = ${response.toString()}');
//response = {"ret":200,"data":"密码修改成功","msg":""}
//response = {"ret":200,"data":"原密码错误","msg":""}
if (response.statusCode == 200) {
if (response.data["data"].indexOf('成功') > 0) {
ret = true;
print('密码修改成功');
print('response.data["data"] = ${response.data["data"]}');
} else {
print('密码修改失败:${response.data["data"]}!');
Fluttertoast.showToast(
msg: '密码修改失败:${response.data["data"]}!',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.CENTER,
);
}
print('密码修改过程正常完成');
} else {
throw Exception('后端接口出现异常,请检测代码和服务器情况.........');
}
} catch (e) {
print('密码修改过程异常...');
print('ERROR:======>${e}');
Fluttertoast.showToast(
msg: 'ERROR:======>${e}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
return ret;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("修改密码",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.only(top: 30, bottom: 20, left: 20, right: 20),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
// child: Image.network(
// 'https://www.itying.com/images/flutter/list5.jpg',
// fit: BoxFit.cover),
),
),
SizedBox(height: 50),
JdText(
height: ScreenUtil().setHeight(300),
title: '旧密码:',
text: "请输入旧密码",
password: true,
onChanged: (String value) {
// print(value);
oldPassword = value;
},
endBtn: 'ShowHiddenBtn',
),
SizedBox(height: 20),
JdText(
height: ScreenUtil().setHeight(300),
title: '新密码:',
text: "请输入6-12位新密码",
password: true,
onChanged: (String value) {
// print(value);
newPassword1 = value;
},
endBtn: 'ShowHiddenBtn',
),
SizedBox(height: 20),
JdText(
height: ScreenUtil().setHeight(300),
title: '新密码:',
text: "请再次输入6-12位新密码",
password: true,
onChanged: (String value) {
// print(value);
newPassword2 = value;
},
endBtn: 'ShowHiddenBtn',
),
SizedBox(height: 20),
Container(
alignment: Alignment(0, 0),
height: ScreenUtil().setHeight(222),
//width: ScreenUtil().setWidth(142),
padding: EdgeInsets.only(
left: ScreenUtil().setWidth(25), right: ScreenUtil().setWidth(25)),
decoration: new BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
border: new Border.all(width: 1, color: Colors.grey),
),
child: Text('新密码需要6-12位,可以由大小写字母、阿拉伯数字,以及英文 ?、_、!、@、#、\$、%、^、& 等字符组成。',
style: TextStyle(fontSize: 15)),
),
SizedBox(height: 60),
JdButton(
height: ScreenUtil().setHeight(382),
//height: 126,
text: "确认",
color: Colors.blueAccent,
onTop: doModifyPw,
)
],
),
),
);
}
}
+273
View File
@@ -0,0 +1,273 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:audioplayers/audio_cache.dart';
import '../../components/commonFun.dart';
import '../../components/dioFun.dart';
class TakePictuer extends StatefulWidget {
TakePictuer({this.arguments, Key key}) : super(key: key);
var arguments;
@override
_TakePictuerState createState() {
return _TakePictuerState();
}
}
class _TakePictuerState extends State<TakePictuer> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
Image image;
String imagePath;
CameraController _cameraController;
@override
void initState() {
super.initState();
//controller = CameraController(cameras[0], ResolutionPreset.medium); //后置相机
_cameraController = CameraController(cameras[1], ResolutionPreset.medium); //前置相机
_cameraController.initialize().then((_) {
//初始化相机
if (!mounted) {
return;
}
_onCamera(); //开始拍照
setState(() {});
});
}
@override
void dispose() {
_cameraController?.dispose();
super.dispose();
}
//开始拍照
Future<void> _onCamera() async {
await Future.delayed(Duration(milliseconds: 1000), () {
print('开始拍照...');
AudioCache().play(File('audio/yinxiao1064.mp3').path); //播放咔嚓声
onTakePictureButtonPressed();
});
}
@override
Widget build(BuildContext context) {
if (!_cameraController.value.isInitialized) {
return Container();
}
return Scaffold(
key: _scaffoldKey,
// appBar: AppBar(
// automaticallyImplyLeading: false,
// title: Container(
// //获取 appBar 高度 kToolbarHeight,R:\Flutter\FlutterSDK\flutter\packages\flutter\lib\src\material\constants.dart
// height: kToolbarHeight,
// //width: ScreenUtil().screenWidth,
// width: double.infinity,
// child: Text('请拿起手机,眨眨眼 ...'),
// decoration: BoxDecoration(
// gradient: LinearGradient(
// begin: Alignment.centerLeft,
// end: Alignment.centerRight,
// colors: [
// Color.fromRGBO(12, 186, 156, 1),
// Color.fromRGBO(39, 127, 235, 1),
// ],
// ),
// ),
// ),
// ),
body: Container(
decoration: new BoxDecoration(
//color: Colors.black,
color: Colors.transparent,
),
child: Column(
children: [
SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
Container(
alignment: Alignment(0, 0),
child: Text(
'请拿起手机,眨眨眼 ...',
style: TextStyle(fontSize: 18.0, color: Colors.white),
textAlign: TextAlign.center,
),
height: ScreenUtil().setHeight(173),
//越界
//height: kToolbarHeight,
//width: ScreenUtil().screenWidth,
width: double.infinity,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
),
Stack(
children: <Widget>[
Align(
child: _cameraPreviewWidget(),
),
Align(
child: _getImage(),
),
Positioned(
left: ScreenUtil().screenWidth / 3,
top: ScreenUtil().screenHeight / 4,
child: image == null ? getMoreWidget() : _getSuccess(),
),
// Align(
// alignment: Alignment.bottomCenter,
// child: Center(
// child: image == null ? getMoreWidget() : _getSuccess(),
// ),
// ),
],
),
Expanded(child: Container(color: Colors.black))
],
),
),
);
}
//mounted 是 bool 类型,表示当前 State 是否加载到树⾥。
// 常用于判断页面是否释放。比如在程序中有些异步的处理,当处理结束时直接调用setState方法会直接报错,
// 因为页面已经释放(dispose)了,此时无法渲染页面,这时就可以使用mounted来进行判断页面是否被释放,如果释放了就不进行渲染。
// if(mounted){
// setState((){})
// }
void onTakePictureButtonPressed() async {
image = null;
takePicture().then((String filePath) async {
if (mounted) {
setState(() {
imagePath = filePath;
});
if (filePath != null) {
image = Image.file(File(filePath));
print('Picture saved to $filePath');
}
await Future.delayed(Duration(milliseconds: 1000), () {
if (filePath != null) {
if ('FaceLogin' == widget.arguments) {
//人脸验证,直接调用 uploadImage 进行验证登录
faceLoginFun(filePath: filePath, context: context);
} else if ('FaceReg' == widget.arguments) {
//返回获得的人脸图片路径 filePath,等待管理员确认注册
Navigator.pop(context, filePath);
//人脸注册,username 用户名,filePath 人脸图片路径
//faceRegFun(username: 'admin', filePath: filePath);
}
}
});
}
});
}
Future<String> takePicture() async {
if (!_cameraController.value.isInitialized) {
print('Error: select a camera first.');
return null;
}
final Directory extDir = await getApplicationDocumentsDirectory();
final String dirPath = '${extDir.path}/Pictures/flutter_test';
await Directory(dirPath).create(recursive: true);
final String filePath = '$dirPath/${timestamp()}.jpg';
if (_cameraController.value.isTakingPicture) {
// A capture is already pending, do nothing.
return null;
}
try {
await _cameraController.takePicture(filePath);
} on CameraException catch (e) {
print('e = ${e.toString()}');
return null;
}
return filePath;
}
//拍照成功
Widget _getSuccess({String text = '拍照成功!'}) {
if (image == null || _cameraController == null || !_cameraController.value.isInitialized) {
return Container(); //不能放回null,否则Stack会报错
} else {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(
Icons.check,
size: 60,
color: Colors.white,
),
SizedBox(
height: 10,
),
Text(
text,
style: TextStyle(
fontSize: 30.0, // 文字大小
color: Colors.white, // 文字颜色
),
),
],
),
);
}
}
//加载照片
Widget _getImage() {
if (image == null || _cameraController == null || !_cameraController.value.isInitialized) {
return Container(); //不能放回null,否则Stack会报错
} else {
return Center(
child: AspectRatio(
aspectRatio: _cameraController.value.aspectRatio,
child: image,
),
);
}
}
Widget _cameraPreviewWidget() {
if (_cameraController == null || !_cameraController.value.isInitialized) {
return const Text(
'正在启动相机...',
style: TextStyle(
color: Colors.white,
fontSize: 24.0,
fontWeight: FontWeight.w900,
),
);
} else {
return AspectRatio(
aspectRatio: _cameraController.value.aspectRatio,
child: CameraPreview(_cameraController),
);
}
}
}
@@ -0,0 +1,368 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dart:convert';
//import 'messages_data.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
class listMessagesData {
List listMessages = [];
int listIndex = 0;
}
class MessagesView extends StatefulWidget {
//MessagesView({Key key, this.title, this.mapData}) : super(key: key);
MessagesView({
@required this.title,
this.listIndex,
Key key,
}) : super(key: key);
String title;
int listIndex = 0;
List listMessages;
Map<String, listMessagesData> mapListMessagesData;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<MessagesView> {
@override
void initState() {
// TODO: implement initState
super.initState();
setInit();
}
String strContent = '';
setInit() async {
widget.mapListMessagesData = Map();
widget.mapListMessagesData['收到的消息'] = listMessagesData();
widget.mapListMessagesData['发送的消息'] = listMessagesData();
widget.mapListMessagesData['收到的消息'].listMessages = listMessagesInbox2;
widget.mapListMessagesData['发送的消息'].listMessages = listMessagesOutbox2;
selectValue = widget.title;
switch (selectValue) {
case '收到的消息':
//第一次调用时widget.listIndex是由外面传入的,不能覆盖widget.listIndex,
// 所以单独抽离出一个不会覆盖widget.listIndex的函数
onRadioBtnInboxSet();
break;
case '发送的消息':
onRadioBtnOutboxSet();
break;
}
widget.listMessages = widget.mapListMessagesData[selectValue].listMessages;
getContent();
}
getPreBtn_NextBtn() {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: null,
);
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: null,
);
if (widget.listIndex > 0 && widget.listMessages.length > 0) {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: () async {
if (widget.listIndex > 0) {
widget.listIndex--;
getContent();
}
},
);
}
if (widget.listIndex < (widget.listMessages.length - 1) && widget.listMessages.length > 0) {
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: () async {
if (widget.listIndex < widget.listMessages.length - 1) {
widget.listIndex++;
getContent();
}
},
);
}
}
getContent() async {
if (widget.listMessages.isEmpty) {
strContent = '';
widget.mapListMessagesData[selectValue].listIndex = widget.listIndex = 0;
} else {
widget.mapListMessagesData[selectValue].listIndex = widget.listIndex;
strContent = "第 ${widget.listIndex + 1} 条(共 ${widget.listMessages.length} 条)" +
"\n" +
"时间:" +
widget.listMessages[widget.listIndex]['date'] +
", " +
widget.listMessages[widget.listIndex]['time'] +
"\n\n" +
"内容:" +
widget.listMessages[widget.listIndex]['content'];
}
getPreBtn_NextBtn();
setState(() {});
}
var selectValue;
//解决第一次进入报错问题。因为getPreBtn_NextBtn()还未执行,preBtn和nextBtn为空
Widget preBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('上一条'),
onPressed: null,
),
);
Widget nextBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('下一条'),
onPressed: null,
),
);
Widget getBtnSizeColor(
{@required title,
width = 70.0,
height = 35.0,
//colorBK = Colors.white12,
txtColor = Colors.black,
fontSize = 16.0,
bottomBorder = false,
onPressedFun}) {
return Container(
//Failed assertion: line 285 pos 15: 'color == null || decoration == null':
// Cannot provide both a color and a decoration
//color: colorBK, //onPressedFun为null时无效
width: width,
height: height,
decoration: BoxDecoration(
border: bottomBorder ? Border(bottom: BorderSide(width: 1, color: Colors.blue)) : null,
),
child: FlatButton(
padding: EdgeInsets.all(0),
textColor: txtColor,
child: Text(title, style: TextStyle(fontSize: fontSize)),
onPressed: onPressedFun,
),
);
}
Widget radioBtnInbox;
Widget radioBtnOutbox;
//第一次调用时widget.listIndex是由外面传入的,不能覆盖widget.listIndex,
// 所以单独抽离出一个不会覆盖widget.listIndex的函数
onRadioBtnInboxSet() {
radioBtnInbox = getBtnSizeColor(
title: '收到的消息',
width: 100.0,
onPressedFun: onRadioBtnInbox,
//colorBK: Colors.white,
txtColor: Colors.blue,
bottomBorder: true);
radioBtnOutbox = getBtnSizeColor(
title: '发送的消息', width: 100.0, onPressedFun: onRadioBtnOutbox, txtColor: Colors.black38);
}
onRadioBtnInbox() {
setState(() {
selectValue = '收到的消息';
onRadioBtnInboxSet();
widget.listMessages = widget.mapListMessagesData[selectValue].listMessages;
widget.listIndex = widget.mapListMessagesData[selectValue].listIndex;
getContent();
});
}
onRadioBtnOutboxSet() {
radioBtnInbox = getBtnSizeColor(
title: '收到的消息', width: 100.0, onPressedFun: onRadioBtnInbox, txtColor: Colors.black38);
radioBtnOutbox = getBtnSizeColor(
title: '发送的消息',
width: 100.0,
onPressedFun: onRadioBtnOutbox,
//colorBK: Colors.white,
txtColor: Colors.blue,
bottomBorder: true);
}
onRadioBtnOutbox() {
setState(() {
selectValue = '发送的消息';
onRadioBtnOutboxSet();
widget.listMessages = widget.mapListMessagesData[selectValue].listMessages;
widget.listIndex = widget.mapListMessagesData[selectValue].listIndex;
getContent();
});
}
Future<bool> alertDialog(String title, String content, var onPresse) async {
return await showDialog(
barrierDismissible: false, //表示点击灰色背景的时候是否消失弹出框
context: context,
builder: (context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: <Widget>[
FlatButton(
child: Text("确定"),
onPressed: onPresse,
),
FlatButton(
child: Text("取消"),
onPressed: () {
Navigator.pop(context, false);
},
),
],
);
},
);
}
@override
Widget build(BuildContext context) {
Size mediaSize = MediaQuery.of(context).size;
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
//SystemNavigator.pop(); //退出App
Navigator.pop(context); //返回
},
),
centerTitle: true,
elevation: 0,
backgroundColor: Colors.white,
title: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 主轴元素的排序方式(水平布局中,X轴是主轴)
crossAxisAlignment: CrossAxisAlignment.end, // 次轴元素的排序方式
children: <Widget>[
radioBtnInbox,
radioBtnOutbox,
],
),
),
actions: [
IconButton(
icon: Icon(Icons.close),
onPressed: () async {
Navigator.pop(context); //关闭弹框,播放输入视频地址
},
),
SizedBox(
width: 10,
),
],
),
body: Container(
alignment: Alignment(0, 0),
child: Container(
child: Column(
children: <Widget>[
Container(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
width: double.infinity,
height: mediaSize.height * 0.75,
child: SingleChildScrollView(
child: Container(
child: Text(strContent),
),
),
),
Divider(
color: Colors.blue,
),
SizedBox(
height: 6,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(
text: "复制",
onPressedFun: () {
// Flutter 复制文本到剪贴板
Clipboard.setData(ClipboardData(
text: ' ' +
selectValue +
'\n\n' +
widget.listMessages[widget.listIndex]['content']));
//showToast('帮助信息已复制到剪贴板', textAlign: TextAlign.left);
Fluttertoast.showToast(msg: '帮助信息已复制到剪贴板', gravity: ToastGravity.CENTER);
//Navigator.pop(context, ret);
}),
getBtnSizeX(
text: "删除",
onPressedFun: () async {
//Navigator.pop(context); //关闭弹框,播放输入视频地址
bool ret = await alertDialog('删除确认', '是否确定要删除当前项目?', () {
if (0 == selectValue.compareTo('收到的消息')) {
listMessagesInbox2.removeAt(widget.listIndex);
widget.mapListMessagesData['收到的消息'].listMessages = listMessagesInbox2;
writeJSON(json.encode(listMessagesInbox2), 'listMessagesInbox02.json');
} else if (0 == selectValue.compareTo('发送的消息')) {
listMessagesOutbox2.removeAt(widget.listIndex);
widget.mapListMessagesData['发送的消息'].listMessages = listMessagesOutbox2;
writeJSON(
json.encode(listMessagesOutbox2), 'listMessagesOutbox02.json');
}
if (widget.listIndex > 0) {
widget.listIndex--;
}
widget.listMessages =
widget.mapListMessagesData[selectValue].listMessages;
getContent();
Navigator.pop(context);
});
}),
preBtn,
nextBtn,
],
),
],
),
),
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
@@ -0,0 +1,229 @@
List listMessagesOutbox = [
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
{
"title": '工作汇报',
"date": '20200325',
"time": '09:19',
"content": "已经处理了7个黑烟事件的初审和推送工作"
},
{
"title": "数据统计",
"date": '20200608',
"time": '13:55',
"content": "已经完成2020年4月份的黑烟事件数据统计工作",
},
];
List listMessagesInbox = [
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
{
"title": '三千多人预约办事每天只放47个号 这县被国办通报!',
"date": '20200311',
"time": '10:23',
"content": "2020年10月,按照国务院第七次大督查的统一部署,14个国务院督查组分赴14个省(区、市)"
"和新疆生产建设兵团开展实地督查。督查发现,部分地方和部门仍存在违规设置行政审批环节,"
"擅自构筑市场准入壁垒等问题,推进“一网通办”、“只进一扇门”、“最多跑一次”还有堵点障碍。",
},
{
"title": "阿根廷举行马拉多纳遗体告别仪式:棺椁覆盖10号球衣",
"date": '20200317',
"time": '16:02',
"content": "【马拉多纳遗体告别仪式:棺椁覆盖10号球衣】阿根廷传奇球星马拉多纳的告别仪式正在举行中,"
"阿根廷TN电视台直播的画面显示,马拉多纳的棺材上覆盖着阿根廷国旗和10号球衣,"
"球迷排队进入总统府玫瑰宫向这位传奇球星告别。(中国日报网)",
},
];
@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'message_content.dart';
//import 'messages_data.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../components/customDialogG.dart';
class MessagesInbox extends StatefulWidget {
MessagesInbox({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<MessagesInbox> {
Widget _getListTile(BuildContext context, index) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: new Text(listMessagesInbox2[index]['date'], style: TextStyle(fontSize: 10)),
subtitle: Text(listMessagesInbox2[index]['time'], style: TextStyle(fontSize: 10)),
trailing: Container(
width: 260,
child: Text(
listMessagesInbox2[index]['title'],
maxLines: 1,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => MessagesView(
// title: '收到的消息', mapData: listMessagesInbox2[index])));
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MessagesView(title: '收到的消息', listIndex: index),
),
);
// Navigator.push(context, MaterialPageRoute(builder: (context) {
// return MessagesOutbox(
// title: "PeakPlayer帮助信息", mapData: listMessagesInbox2[index]);
// }));
},
onLongPress: () async {
bFlash = false;
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => customDialogG(
// title: '收到的消息',
// index: index),
// ),
// );
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
customDialogG(title: '收到的消息', index: index),
),
// pageBuilder: (context, animation, secondaryAnimation) {
// return Scaffold(
// backgroundColor: Colors.transparent,
// body: SafeArea(
// child: Stack(
// children: <Widget>[
// Text('text'),
// //...
// ],
// ),
// ),
// );
// },
).then((value) {
print('Page2_Contacts bFlash = $bFlash');
if (bFlash) {
setState(() {});
}
});
},
),
Divider(
height: 1.0,
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
children: <Widget>[
Expanded(
//Flutter Column套ListView不显示,可将ListView用Expanded包裹起来。
child: ListView.builder(
itemCount: listMessagesInbox2.length,
itemBuilder: _getListTile,
),
),
],
),
),
);
}
}
@@ -0,0 +1,42 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'messages_inbox.dart';
import 'messages_outbox.dart';
class MessagesManagePage extends StatefulWidget {
MessagesManagePage({Key key}) : super(key: key);
@override
_MessagesManagePageState createState() => _MessagesManagePageState();
}
class _MessagesManagePageState extends State<MessagesManagePage> {
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 2,
child: Scaffold(
appBar: AppBar(
title: Text('消息管理'),
centerTitle: true,
bottom: TabBar(
labelColor: Colors.blueAccent,
unselectedLabelColor: Colors.black26,
tabs: <Widget>[Tab(text: "收件箱"), Tab(text: "已发送")],
),
),
body: TabBarView(
//flutter tabbar禁止手势滑动-OK
physics: new NeverScrollableScrollPhysics(),
children: <Widget>[
MessagesInbox(),
MessagesOutbox(),
],
),
),
// theme: ThemeData(
// primarySwatch: Colors.yellow
// ),
);
}
}
@@ -0,0 +1,95 @@
import 'package:flutter/material.dart';
import 'message_content.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../components/customDialogG.dart';
class MessagesOutbox extends StatefulWidget {
MessagesOutbox({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<MessagesOutbox> {
Widget _getListTile(BuildContext context, index) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: new Text(listMessagesOutbox2[index]['date'],
style: TextStyle(fontSize: 10)),
subtitle: Text(listMessagesOutbox2[index]['time'],
style: TextStyle(fontSize: 10)),
trailing: Container(
width: 260,
child: Text(
listMessagesOutbox2[index]['title'],
maxLines: 1,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => MessagesView(
// title: '发送的消息', mapData: listMessagesOutbox2[index])));
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => MessagesView(
title: '发送的消息',
listIndex: index),
),
);
// Navigator.push(context, MaterialPageRoute(builder: (context) {
// return MessagesOutbox(
// title: "PeakPlayer帮助信息", mapData: listMessagesOutbox2[index]);
// }));
},
onLongPress: () {
bFlash = false;
Navigator.of(context).push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
customDialogG(title: '发送的消息', index: index),
),
).then((value) {
print('Page2_Contacts bFlash = $bFlash');
if (bFlash) {
setState(() {});
}
});
},
),
Divider(
height: 1.0,
),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Column(
children: <Widget>[
Expanded(
//Flutter Column套ListView不显示,可将ListView用Expanded包裹起来。
child: ListView.builder(
itemCount: listMessagesOutbox2.length,
itemBuilder: _getListTile,
),
),
],
),
),
);
}
}
@@ -0,0 +1,198 @@
import 'package:flutter/material.dart';
import '../../../widget/JdButton.dart';
import '../../../services/EventBus.dart';
import '../01_messages/messages_manage.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
import 'dart:convert';
import '../../../res/listContacts.dart';
class ContactAdd extends StatefulWidget {
ContactAdd({@required this.contactIndex, Key key}) : super(key: key);
int contactIndex;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<ContactAdd> {
//List<TextEditingController> listController;
bool changed = false;
void initState() {
// TODO: implement initState
super.initState();
getListFlields();
}
getListFlields() {
//在listContacts2末尾添加一条记录,这种方式会导致添加后,同时修改被拷贝的记录
// listContacts2.add(listContacts2[widget.contactIndex]);
// widget.contactIndex = listContacts2.length - 1;
//
// listController = List.generate(listContacts2[widget.contactIndex].length, (index) {
// String key = listContacts2[widget.contactIndex].keys.elementAt(index);
// listContacts2[widget.contactIndex][key] = ''; //清空内容
// return TextEditingController();
// });
//在listContacts2末尾添加一条记录
//添加硬数据方式不好,若listContacts2的字段修改后,便可能导致问题
// var item = {
// "姓名": '张三',
// "登录名称": 'ZhangSan',
// "登录密码": '**********',
// "部门": '办公室',
// "职务": '主任',
// "手机": '133xxxxxxxx',
// "办公电话": '0831xxxxxxx',
// "邮箱": '1234@qq.com',
// "权限": '管理员',
// "备注": '示例用户',
// };
// //map遍历
// //usrMap.forEach((k,v) => print('${k}: ${v}'));
// item.forEach((key, value) {
// item[key] = ''; //清空内容
// });
//在listContacts2末尾添加一条记录,动态生成item中的元素
Map item = {};
listContacts2[widget.contactIndex].forEach((key, value) {
item[key] = ''; //为item添加元素
});
listContacts2.add(item);
widget.contactIndex = listContacts2.length - 1;
//setState(() {});
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
if (changed) {
print("writeJSON()");
writeJSON(json.encode(listContacts2), 'listContacts02.json');
} else {
print("removeLast()");
listContacts2.removeLast(); //删除添加的末尾元素
}
eventBus.fire(new UserEvent('登录成功...'));
}
doLogin() async {
Navigator.pop(context); //返回
return;
}
OnTap_messages_manage() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => MessagesManagePage()));
}
//自定义方法
static onNullFun() {}
Widget getTrail(String key, int index, double widthTrail) {
return Container(
alignment: Alignment(1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
child: TextField(
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
decoration: InputDecoration(
hintText: '請輸入字段信息',
//border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
),
//controller: listController[index],
//利用控制器初始化文本
onChanged: (value) {
listContacts2[widget.contactIndex][key] = value;
bFlash = changed = true;
print("ContactAdd bFlash = $bFlash");
},
),
);
}
Widget _getListTile(String key, int index, double widthTrail,
{onTapFun = onNullFun, onLongPressFun = onNullFun, size = 16.0}) {
return ListTile(
//leading: new Icon(Icons.phone),
title: Text('${mapUserInfoText[key]} :', style: TextStyle(fontSize: 16)),
trailing: getTrail(key, index, widthTrail),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () {},
onLongPress: () {},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("修改联系人"),
centerTitle: true,
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
//Flutter Column套ListView不显示,可将ListView用Expanded包裹起来。
// child: ListView.builder(
// itemCount: listFlields.length,
// itemBuilder: _getListTileFields,
// ),
//https://www.it1352.com/2028416.html
//用Map而不是List的Flutter ListView(Flutter listview with Map instead of List)
//listContacts2[widget.contactIndex]
child: ListView.builder(
itemCount: listContacts2[widget.contactIndex].length,
itemBuilder: (BuildContext context, index) {
String key = listContacts2[widget.contactIndex].keys.elementAt(index);
return Column(
children: <Widget>[
_getListTile(key, index, 220.0),
Divider(
height: 1.0,
),
],
);
},
),
),
],
),
),
);
}
//https://www.it1352.com/2028416.html
//用Map而不是List的ListView.builder
//Its a little late but You could also try this. Map values = snapshot.data;
getMap() {
Map values = listContacts2[widget.contactIndex];
return new ListView.builder(
itemCount: values.length,
itemBuilder: (BuildContext context, int index) {
String key = values.keys.elementAt(index);
return new Column(
children: <Widget>[
new ListTile(
title: new Text("$key"),
subtitle: new Text("${values[key]}"),
),
new Divider(
height: 2.0,
),
],
);
},
);
}
}
@@ -0,0 +1,162 @@
import 'package:flutter/material.dart';
import '../../../services/EventBus.dart';
import '../01_messages/messages_manage.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
import 'dart:convert';
import '../../../res/listContacts.dart';
class ContactModify extends StatefulWidget {
ContactModify({@required this.contactIndex, Key key}) : super(key: key);
int contactIndex;
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<ContactModify> {
List<TextEditingController> listController;
bool changed = false;
void initState() {
// TODO: implement initState
super.initState();
getListFlields();
}
String getUserText3(int index, String key) {
String str = (listContacts2[index][key] is String) ? listContacts2[index][key] : '';
return str;
}
getListFlields() {
listController = List.generate(listContacts2[widget.contactIndex].length, (index) {
String key = listContacts2[widget.contactIndex].keys.elementAt(index);
//return TextEditingController(text: listContacts2[widget.contactIndex][key]);
return TextEditingController(text: getUserText3(widget.contactIndex, key));
});
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
if (changed) {
writeJSON(json.encode(listContacts2), 'listContacts02.json');
}
eventBus.fire(new UserEvent('登录成功...'));
}
doLogin() async {
Navigator.pop(context); //返回
return;
}
OnTap_messages_manage() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => MessagesManagePage()));
}
//自定义方法
static onNullFun() {}
Widget getTrail(String key, int index, double widthTrail) {
return Container(
alignment: Alignment(1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
child: TextField(
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
decoration: InputDecoration(
hintText: '請輸入字段信息',
//border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
),
controller: listController[index],
enabled: mapUserInfoModifyable[key],
//利用控制器初始化文本
onChanged: (value) {
listContacts2[widget.contactIndex][key] = value;
bFlash = changed = true;
print("ContactAdd bFlash = $bFlash");
},
),
);
}
Widget _getListTile(String key, int index, double widthTrail,
{onTapFun = onNullFun, onLongPressFun = onNullFun, size = 16.0}) {
return ListTile(
//leading: new Icon(Icons.phone),
title: Text('${mapUserInfoText[key]} :', style: TextStyle(fontSize: 16)),
trailing: getTrail(key, index, widthTrail),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () {},
onLongPress: () {},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("修改联系人"),
centerTitle: true,
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
//Flutter Column套ListView不显示,可将ListView用Expanded包裹起来。
// child: ListView.builder(
// itemCount: listFlields.length,
// itemBuilder: _getListTileFields,
// ),
//listContacts2[widget.contactIndex]
child: ListView.builder(
itemCount: listContacts2[widget.contactIndex].length,
itemBuilder: (BuildContext context, index) {
String key = listContacts2[widget.contactIndex].keys.elementAt(index);
return Column(
children: <Widget>[
_getListTile(key, index, 220.0),
Divider(
height: 1.0,
),
],
);
},
),
),
],
),
),
);
}
//https://www.it1352.com/2028416.html
//用Map而不是List的ListView.builder
//Its a little late but You could also try this. Map values = snapshot.data;
getMap() {
Map values = listContacts2[widget.contactIndex];
return new ListView.builder(
itemCount: values.length,
itemBuilder: (BuildContext context, int index) {
String key = values.keys.elementAt(index);
return new Column(
children: <Widget>[
new ListTile(
title: new Text("$key"),
subtitle: new Text("${values[key]}"),
),
new Divider(
height: 2.0,
),
],
);
},
);
}
}
@@ -0,0 +1,274 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import '../../../components/customDialogH.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../res/listContacts.dart';
import '../../../services/EventBus.dart';
import '../../../services/Storage.dart';
import '../../../widget/JdButton.dart';
class PersonalData extends StatefulWidget {
PersonalData({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<PersonalData> {
List<TextEditingController> listController = [];
String imagePath = '';
Image _image;
void initState() {
// TODO: implement initState
getListFlields();
super.initState();
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
eventBus.fire(new UserEvent('登录成功...'));
}
getListFlields() async {
Storage.getString('userAvatarPath').then((value) {
if (null != value) {
imagePath = value;
}
});
print('imagePath = $imagePath');
//mapUserInfo = mapUserInfoRet['data']['profile'];
await getMyUserinfo();
// print('mapUserInfoRet = $mapUserInfoRet');
// print('mapUserInfo = $mapUserInfo');
listController = List.generate(mapUserInfo.length, (index) {
String key = mapUserInfo.keys.elementAt(index);
if ("reg_time" == key) {
var strtime = DateTime.fromMillisecondsSinceEpoch(mapUserInfo[key]); //将拿到的时间戳转化为日期
print('时间戳:${mapUserInfo[key]}');
print('转换为日期时间:${strtime.toLocal().toString()}');
// I/flutter (25364): 时间戳:1606653977
// I/flutter (25364): 转换为日期时间:1970-01-19 14:17:33.977
return TextEditingController(text: strtime.toLocal().toString());
} else {
var controller = TextEditingController(text: mapUserInfo[key].toString());
controller.selection = TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: '${controller.text}'.length),
);
return controller;
}
});
setState(() {});
}
Widget getTrail(String key, int index, double widthTrail) {
if (0 == listController.length) {
return Container();
}
//print('key = $key');
if ('avatar' == key) {
if (imagePath.isEmpty) {
imagePath = listController[index].text;
}
return getAvatar(width: widthTrail);
} else {
return Container(
alignment: Alignment(1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
child: TextField(
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
decoration: InputDecoration(
//hintText: '請輸入字段信息',
border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
),
controller: listController[index],
enabled: mapUserInfoModifyable[key],
//利用控制器初始化文本
onChanged: (value) {
mapUserInfo[key] = value;
},
),
);
}
}
Future<String> doContacts() async {
bFlash = false;
return showDialog(
context: context,
builder: (BuildContext context) {
return customDialogH(
title: "请选择头像修改操作",
content: "头像修改",
index: 0,
);
},
).then((value) {
if (null == value) {
return;
}
imagePath = value;
print('Page2_Contacts bFlash = $bFlash');
if (imagePath?.isNotEmpty) {
Storage.setString('userAvatarPath', imagePath);
_image = Image.file(File(imagePath), fit: BoxFit.cover);
setState(() {});
}
});
}
Widget getAvatar({double width = 260.0}) {
if (imagePath.isEmpty) {
_image = Image.asset('assets/images/user.png', fit: BoxFit.cover);
} else {
String head = imagePath.substring(0, 4).trim().toLowerCase();
if ('http' == head) {
_image = Image.network(imagePath, fit: BoxFit.cover);
} else {
_image = Image.file(File(imagePath), fit: BoxFit.cover);
}
}
return Container(
alignment: Alignment(-1, 0),
width: width,
child: InkWell(
onTap: () async {
//doContacts();
},
child: Container(
width: 40,
child: _image,
),
),
);
}
static onNullFun() {}
Widget _getListTile(String key, int index, double widthTrail,
{onTapFun = onNullFun, onLongPressFun = onNullFun, size = 16.0}) {
return ListTile(
//leading: new Icon(Icons.phone),
title: Text(mapUserInfoText.containsKey(key) ? '${mapUserInfoText[key]} :' : '$key :',
style: TextStyle(fontSize: 16)),
trailing: getTrail(key, index, widthTrail),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
// if ('avatar' == key) {
// print('选择图片或拍照');
// await doContacts();
// }
},
onLongPress: () {},
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("个人资料",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
//https://www.it1352.com/2028416.html
//用Map而不是List的Flutter ListView.builder(Flutter listview with Map instead of List)
child: ListView.builder(
itemCount: mapUserInfo.length,
itemBuilder: (BuildContext context, index) {
String key = mapUserInfo.keys.elementAt(index);
return Column(
children: <Widget>[
_getListTile(key, index, 220.0),
Divider(
height: 1.0,
),
],
);
},
),
),
SizedBox(height: 40),
JdButton(
height: 126,
width: 899,
text: "确认",
color: Colors.blueAccent,
onTop: () async {
Navigator.pop(context);
},
),
SizedBox(height: 40),
],
),
),
);
}
}
@@ -0,0 +1,221 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import '../../../widget/JdButton.dart';
class MyFeedback extends StatefulWidget {
MyFeedback({Key key}) : super(key: key);
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<MyFeedback> {
void initState() {
// TODO: implement initState
super.initState();
}
doOK() {
Navigator.pop(context); //返回
}
int radioSelect = 0;
String opinionText = '';
//监听登录页面销毁的事件
dispose() {
super.dispose();
}
Widget getTextField() {
return Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(4.0)),
border: new Border.all(width: 1, color: Colors.blue),
),
constraints: BoxConstraints(
maxHeight: 240.0,
maxWidth: MediaQuery.of(context).size.width,
minHeight: 240.0,
minWidth: MediaQuery.of(context).size.width,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(width: 10),
Expanded(
child: TextField(
style: TextStyle(fontSize: 16),
keyboardType: TextInputType.multiline,
maxLines: null,
//不限制行数
decoration: InputDecoration(
hintText: '請輸入反馈问题的详细描述内容',
border: InputBorder.none, //TextField去掉下划线
//border: OutlineInputBorder(),
),
onChanged: (val) {
opinionText = val;
},
),
),
SizedBox(width: 10),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("意见反馈",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 10),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
),
),
SizedBox(height: 10),
Text('请选择问题类型'),
getRadioRow(),
Text('请輸入问题描述'),
SizedBox(height: 10),
getTextField(),
SizedBox(height: 40),
JdButton(
height: 126,
text: "确认",
color: Colors.blueAccent,
onTop: doOK,
)
],
),
),
);
}
Widget getRadio(int index) {
return Container(
alignment: Alignment(1, -1),
height: 30,
width: 30,
child: Radio(
value: index,
onChanged: (v) {
setState(() {
radioSelect = v;
});
},
groupValue: radioSelect,
),
);
}
Widget getRadioRow() {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"投诉",
style: TextStyle(
color: (0 == radioSelect) ? Colors.blue : null,
fontWeight: (0 == radioSelect) ? FontWeight.bold : null,
),
),
getRadio(0),
SizedBox(width: 25),
Text(
"故障",
style: TextStyle(
color: (1 == radioSelect) ? Colors.blue : null,
fontWeight: (1 == radioSelect) ? FontWeight.bold : null,
),
),
getRadio(1),
SizedBox(width: 25),
Text(
"建议",
style: TextStyle(
color: (2 == radioSelect) ? Colors.blue : null,
fontWeight: (2 == radioSelect) ? FontWeight.bold : null,
),
),
getRadio(2),
SizedBox(width: 25),
Text(
"其他",
style: TextStyle(
color: (3 == radioSelect) ? Colors.blue : null,
fontWeight: (3 == radioSelect) ? FontWeight.bold : null,
),
),
getRadio(3),
],
);
}
}
+389
View File
@@ -0,0 +1,389 @@
import 'dart:async';
import 'dart:io';
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
///1、导入相关包
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:hyzp_ybqx/components/doJSON.dart';
import 'package:open_file/open_file.dart';
import 'package:package_info/package_info.dart';
import 'package:path_provider/path_provider.dart';
import 'package:progress_dialog/progress_dialog.dart';
import '../../../components/commonFun.dart';
import '../../../widget/JdButton.dart';
///版本更新頁面
class MyUpdated extends StatefulWidget {
MyUpdated({Key key, this.ver, this.date, this.theContext}) : super(key: key);
String ver = '1.0.0';
String date = '';
BuildContext theContext;
_MyUpdatedState createState() => _MyUpdatedState();
}
class _MyUpdatedState extends State<MyUpdated> {
//2、声明变量
int _stampAppCompile = -1;
String _dateNewver = '';
Map _mapVer = {};
String serviceVersionCode = '';
String appId = '';
ProgressDialog pr;
String apkName = 'app-release.apk';
String appPath = '';
ReceivePort _port = ReceivePort();
void initState() {
// 0、初始化FlutterDownLoader。版本更新初始化,放在这里会报错,初始化失败
// WidgetsFlutterBinding.ensureInitialized();
if (!bFlutterDownloader_initialize) {
FlutterDownloader.initialize(debug: true).then((value) {
//3、在initState中初始化
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen(_updateDownLoadInfo);
FlutterDownloader.registerCallback(_downLoadCallback);
getNewverUrl().then((value) {
_mapVer = value;
print('_mapVer = ${_mapVer}');
});
bFlutterDownloader_initialize = true;
});
} else {
//3、在initState中初始化
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen(_updateDownLoadInfo);
FlutterDownloader.registerCallback(_downLoadCallback);
getNewverUrl().then((value) {
_mapVer = value;
print('_mapVer = ${_mapVer}');
//I/flutter (12498): _mapVer = {id: 1, ver: 1.0.0, miaos: 版本说明,
// downurl: http://www.sctastech.com/download/hyzp_20210425.apk, updatetime: 1620632231}
print('oldVer = ${widget.ver}');
_mapVer['ver'] = '1.3.1';
print('newVer = ${_mapVer['ver']}');
// I/flutter ( 1872): oldVer = 1.3.0
// I/flutter ( 1872): newVer = 1.3.1
///从字符串时间获取秒时间戳:int getStampFromString(String strTime)
// _stampAppCompile = getStampFromString(widget.date.replaceAll('.', '-'));
// //timeStamp可以是int类型或String类型的时间戳(秒):String getFtpdir_YYYYMMDD(var timeStamp)
// _dateNewver = getFtpdir_YYYYMMDD(_mapVer['updatetime'], sep: '.');
// print('_stampAppCompile = $_stampAppCompile');
// print('_mapVer[\'updatetime\'] = ${_mapVer['updatetime']}');
// print('widget.date = ${widget.date}');
// print('_dateNewver = $_dateNewver');
// I/flutter (30820): _stampAppCompile = 1620403200
// I/flutter (30820): _mapVer['updatetime'] = 1620632231
// I/flutter (30820): widget.date = 2021.05.08
// I/flutter (30820): _dateNewver = 2021.05.10
});
}
super.initState();
}
//4、判断,自动更新
// 版本比较
Future verCompare({String newVer, String oldVer}) async {
List listNewVer = await tran2int(newVer.split('.'));
List listOldVer = await tran2int(oldVer.split('.'));
int len = listNewVer.length;
for (int i = 0; i < len; i++) {
if (listNewVer[i] > listOldVer[i]) {
return true;
}
}
return false;
}
Future tran2int(List _list) async {
List listRet = [];
int len = _list.length;
for (int i = 0; i < len; i++) {
listRet.add(int.parse(_list[i].trim()));
}
return listRet;
}
@override
Future afterFirstLayout(BuildContext context) async {
// 如果是android,则执行热更新
if (Platform.isAndroid) {
verCompare(newVer: _mapVer['ver'], oldVer: widget.ver).then((value) {
if (value) {
print('value = $value');
//_getNewVersionAPP(context);
serviceVersionCode = _mapVer['ver'];
//appId = res.data['id'];
//_checkVersionCode();
_showNewVersionAppDialog();
}
});
}
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
}
doLogin() async {
//临时跳转
//Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
afterFirstLayout(context).then((value) {});
//Navigator.pop(context); //返回
return;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)),
// 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight),
//留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("版本更新",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 5, right: 5),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
// child: Image.network(
// 'https://www.itying.com/images/flutter/list5.jpg',
// fit: BoxFit.cover),
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 60),
Text('宜宾市黑烟车电子抓拍系统', style: TextStyle(fontSize: 20)),
Text('v${widget.ver}(${widget.date})', style: TextStyle(fontSize: 20)),
SizedBox(height: 60),
Text('© 宜宾市生态环境局 四川省踏石科技 版权所有\n服务热线:187-8467-8300',
maxLines: 2, style: TextStyle(fontSize: 16), textAlign: TextAlign.center),
],
),
),
SizedBox(height: 100),
Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: JdButton(
height: 126,
text: "确认",
color: Colors.blueAccent,
onTop: doLogin,
),
),
],
),
),
);
}
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
//5、自动更新代码
/// 执行版本更新的网络请求
_getNewVersionAPP(context) async {
// HttpUtils.send(
// context,
// 'http://update.rwworks.com:8088/appManager/monitor/app/version/check/flutterTempldate',
// ).then((res) {
// serviceVersionCode = res.data["versionNo"];
// appId = res.data['id'];
// _checkVersionCode();
// });
}
/// 检查当前版本是否为最新,若不是,则更新
void _checkVersionCode() {
PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
var currentVersionCode = packageInfo.version;
if (double.parse(serviceVersionCode.substring(0, 3)) >
double.parse(currentVersionCode.substring(0, 3))) {
_showNewVersionAppDialog();
}
});
}
/// 版本更新提示对话框
Future<void> _showNewVersionAppDialog() async {
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: new Row(
children: <Widget>[
new Padding(
padding: const EdgeInsets.fromLTRB(30.0, 0.0, 10.0, 0.0),
child: new Text("发现新版本"))
],
),
content: new Text(serviceVersionCode),
actions: <Widget>[
new FlatButton(
child: new Text('下次再说'),
onPressed: () {
Navigator.of(context).pop();
},
),
new FlatButton(
child: new Text('立即更新'),
onPressed: () {
_doUpdate(context);
},
)
],
);
});
}
/// 执行更新操作
_doUpdate(BuildContext context) async {
Navigator.pop(context);
_executeDownload(context);
}
/// 下载最新apk包
Future<void> _executeDownload(BuildContext context) async {
pr = new ProgressDialog(
context,
type: ProgressDialogType.Download,
isDismissible: true,
showLogs: true,
);
pr.style(message: '准备下载...');
if (!pr.isShowing()) {
pr.show();
}
final path = await _apkLocalPath;
await FlutterDownloader.enqueue(
//url: 'http://update.rwworks.com:8088/appManager/monitor/app/appload/' + appId + '',
url: _mapVer['downurl'],
savedDir: path,
fileName: apkName,
showNotification: true,
openFileFromNotification: true);
}
/// 下载进度回调函数
static void _downLoadCallback(String id, DownloadTaskStatus status, int progress) {
final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
}
/// 更新下载进度框
_updateDownLoadInfo(dynamic data) {
DownloadTaskStatus status = data[1];
int progress = data[2];
if (status == DownloadTaskStatus.running) {
pr.update(progress: double.parse(progress.toString()), message: "下载中,请稍后…");
}
if (status == DownloadTaskStatus.failed) {
if (pr.isShowing()) {
pr.hide();
}
}
if (status == DownloadTaskStatus.complete) {
if (pr.isShowing()) {
pr.hide();
}
_installApk();
}
}
/// 安装apk
Future<Null> _installApk() async {
await OpenFile.open(appPath + '/' + apkName);
}
/// 获取apk存储位置
Future<String> get _apkLocalPath async {
final directory = await getExternalStorageDirectory();
String path = directory.path + Platform.pathSeparator + 'Download';
;
final savedDir = Directory(path);
bool hasExisted = await savedDir.exists();
if (!hasExisted) {
await savedDir.create();
}
this.setState(() {
appPath = path;
});
return path;
}
}
@@ -0,0 +1,386 @@
import 'dart:async';
import 'dart:io';
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
///1、导入相关包
import 'dart:isolate';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:progress_dialog/progress_dialog.dart';
import '../../../components/commonFun.dart';
///版本更新类
class MyUpdatedNew {
MyUpdatedNew(
{this.ver,
this.date,
this.theContext,
this.bStartUpdated = false,
this.bShowNoNewVersion = false}) {
initState();
}
String ver = '1.0.0';
String date = '';
BuildContext theContext;
bool bStartUpdated;
bool bShowNoNewVersion;
//2、声明变量
int _stampAppCompile = -1;
String _dateNewver = '';
Map _mapVer = {};
String serviceVersionCode = '';
String appId = '';
ProgressDialog pr;
String apkName = '';
String appPath = '';
ReceivePort _port = ReceivePort();
void initState() {
// 0、初始化FlutterDownLoader。版本更新初始化,放在这里会报错,初始化失败
// WidgetsFlutterBinding.ensureInitialized();
if (!bFlutterDownloader_initialize) {
FlutterDownloader.initialize(debug: true).then((value) {
registerCallback(first: true);
});
} else {
registerCallback();
}
}
registerCallback({bool first = false}) {
//3、在initState中初始化
/*
D/DownloadWorker( 4745): Update too frequently!!!!, this should be dropped
E/flutter ( 4745): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: NoSuchMethodError: The method 'update' was called on null.
E/flutter ( 4745): Receiver: null
E/flutter ( 4745): Tried calling: update(message: "下载中,请稍后…", progress: 0.0)
E/flutter ( 4745): #0 Object.noSuchMethod (dart:core-patch/object_patch.dart:51:5)
E/flutter ( 4745): #1 MyUpdatedNew._updateDownLoadInfo (package:hyzp_ybqx/pages/MyMsics/05_updated/MyUpdatedNew.dart:251:10)
E/flutter ( 4745): #2 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter ( 4745): #3 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter ( 4745): #4 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter ( 4745): #5 _BufferingStreamSubscription._sendData (dart:async/stream_impl.dart:357:11)
E/flutter ( 4745): #6 _BufferingStreamSubscription._add (dart:async/stream_impl.dart:285:7)
E/flutter ( 4745): #7 _SyncStreamControllerDispatch._sendData (dart:async/stream_controller.dart:808:19)
E/flutter ( 4745): #8 _StreamController._add (dart:async/stream_controller.dart:682:7)
E/flutter ( 4745): #9 _StreamController.add (dart:async/stream_controller.dart:624:5)
E/flutter ( 4745): #10 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)
E/flutter ( 4745):
*/
if (!first) {
// 解决2次进入报错无法下载的问题-OK
// 如果以前注册过必须先移除,否则报错无法下载:DownloadWorker( 4745): Update too frequently!!!!, this should be dropped
IsolateNameServer.removePortNameMapping('downloader_send_port');
// FlutterDownloader.cancelAll();
// FlutterDownloader.remove(taskId: null);
}
IsolateNameServer.registerPortWithName(_port.sendPort, 'downloader_send_port');
_port.listen(_updateDownLoadInfo);
FlutterDownloader.registerCallback(_downLoadCallback);
getNewverUrl().then((value) {
_mapVer = value;
print('_mapVer = ${_mapVer}');
//I/flutter (12498): _mapVer = {id: 1, ver: 1.0.0, miaos: 版本说明,
// downurl: http://www.sctastech.com/download/hyzp_20210425.apk, updatetime: 1620632231}
print('oldVer = ${ver}');
//_mapVer['ver'] = '1.3.1';
print('newVer = ${_mapVer['ver']}');
// I/flutter ( 1872): oldVer = 1.3.0
// I/flutter ( 1872): newVer = 1.3.1
if (first) {
bFlutterDownloader_initialize = true;
}
startUpdated();
});
}
///开始更新过程
Future startUpdated() async {
// 如果是android,则执行热更新
if (Platform.isAndroid) {
verCompare(newVer: _mapVer['ver'], oldVer: ver).then((value) {
if (value) {
print('value = $value');
//_getNewVersionAPP(context);
//appId = res.data['id'];
//_checkVersionCode();
bNewVer = true; //发现新版本
if (bStartUpdated) {
serviceVersionCode = _mapVer['ver'];
_showNewVersionAppDialog();
}
} else if (bShowNoNewVersion) {
// 没有发现新版本
_showNoNewVersionAppDialog();
}
});
}
}
/// 没有发现新版本
Future<void> _showNoNewVersionAppDialog() async {
return showDialog<void>(
context: theContext,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text("没有发现新版本")],
),
content: Container(
//padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
height: ScreenUtil().setHeight(230),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent, width: 1.0),
borderRadius: BorderRadius.circular(5),
),
alignment: Alignment.center,
child: RichText(
textAlign: TextAlign.center,
text: TextSpan(children: [
TextSpan(text: 'NewVer: ', style: TextStyle(fontSize: 17, color: Colors.black)),
TextSpan(
text: '暂无新版本',
style: TextStyle(
fontSize: 17, color: Colors.black, fontWeight: FontWeight.bold)),
]),
),
),
actions: <Widget>[
new FlatButton(
child: new Text('确定'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
/// 版本更新提示对话框
Future<void> _showNewVersionAppDialog() async {
String content1 = "注意:";
String content2 = "新版本下载成功后,将弹出“安装未知应用程序”界面,请";
String content3 = "授权“允许此来源”";
String content4 = ";然后";
String content5 = "稍等几秒钟";
String content6 = ",再";
String content7 = "点击“返回”按钮(一般位于左上角)";
String content8 = ",按照提示即可完成升级过程。若";
String content9 = "升级过程意外中断";
String content10 = ",可重启App再次升级即可。";
return showDialog<void>(
context: theContext,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
insetPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 24.0),
buttonPadding: EdgeInsets.only(bottom: 15, right: 20),
title: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Text("发现新版本")],
),
content: Container(
padding: EdgeInsets.only(
left: ScreenUtil().setHeight(25), right: ScreenUtil().setHeight(10)),
height: ScreenUtil().setHeight(620),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent, width: 1.0),
borderRadius: BorderRadius.circular(5),
),
alignment: Alignment.center,
child: Column(
children: [
RichText(
textAlign: TextAlign.center,
text: TextSpan(children: [
TextSpan(
text: '\nNewVer: ',
style: TextStyle(fontSize: 17, color: Colors.redAccent)),
TextSpan(
text: serviceVersionCode,
style: TextStyle(
fontSize: 17, color: Colors.redAccent, fontWeight: FontWeight.bold)),
]),
),
RichText(
textAlign: TextAlign.justify,
text: TextSpan(children: [
getTextSpan('\n' + content1, color: Colors.blueAccent),
getTextSpan(content2),
getTextSpan(content3, color: Colors.redAccent),
getTextSpan(content4),
getTextSpan(content5, color: Colors.redAccent),
getTextSpan(content6),
getTextSpan(content7, color: Colors.redAccent),
getTextSpan(content8),
getTextSpan(content9, color: Colors.blueAccent),
getTextSpan(content10),
]),
),
],
),
),
actions: <Widget>[
new FlatButton(
child: new Text('立即更新'),
onPressed: () {
/// 执行更新操作
Navigator.pop(context);
_executeDownload(context);
},
),
new FlatButton(
child: new Text('下次再说'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
TextSpan getTextSpan(String _text, {Color color = Colors.black, double fontSize = 15}) {
return TextSpan(text: _text, style: TextStyle(fontSize: fontSize, color: color));
}
/// 下载最新apk包
Future<void> _executeDownload(BuildContext context) async {
pr = new ProgressDialog(
context,
type: ProgressDialogType.Download,
isDismissible: true,
showLogs: true,
);
pr.style(message: '准备下载...');
if (!pr.isShowing()) {
pr.show();
}
final path = await _apkLocalPath;
apkName = getFileName(_mapVer['downurl']);
await FlutterDownloader.enqueue(
//url: 'http://update.rwworks.com:8088/appManager/monitor/app/appload/' + appId + '',
url: _mapVer['downurl'],
savedDir: path,
fileName: apkName,
showNotification: true,
openFileFromNotification: true);
}
/// 下载进度回调函数
static void _downLoadCallback(String id, DownloadTaskStatus status, int progress) {
final SendPort send = IsolateNameServer.lookupPortByName('downloader_send_port');
send.send([id, status, progress]);
}
/// 更新下载进度框
_updateDownLoadInfo(dynamic data) {
DownloadTaskStatus status = data[1];
int progress = data[2];
if (status == DownloadTaskStatus.running) {
pr.update(progress: double.parse(progress.toString()), message: "下载中,请稍后…");
}
if (status == DownloadTaskStatus.failed) {
if (pr.isShowing()) {
pr.hide();
}
}
if (status == DownloadTaskStatus.complete) {
if (pr.isShowing()) {
pr.hide();
}
_installApk();
}
}
/// 安装apk
Future<Null> _installApk() async {
await OpenFile.open(appPath + '/' + apkName);
}
/// 获取apk存储位置
Future<String> get _apkLocalPath async {
final directory = await getExternalStorageDirectory();
String path = directory.path + Platform.pathSeparator + 'Download';
;
final savedDir = Directory(path);
bool hasExisted = await savedDir.exists();
if (!hasExisted) {
await savedDir.create();
}
appPath = path;
// this.setState(() {
// appPath = path;
// });
return path;
}
//4、判断,自动更新
// 版本比较
//R:\FlutterProject\FlutterProject33\hyzp_ybqx\lib\pages\MyMsics\05_updated\MyUpdatedNew.dart line 343
Future verCompare({String newVer, String oldVer}) async {
//解决newVer中不包含字符“+”号报错失败问题
if (newVer.indexOf('+') > -1) {
//解决App.Car_Ver.Getver接口返回值变化后,1.3.11+20210729字符串转换为数字报错问题
print('newVer = $newVer');
newVer = newVer.substring(0, newVer.indexOf('+')); // substring是含头不含尾
print('newVer2 = $newVer');
}
List listNewVer = await tran2int(newVer.split('.'));
List listOldVer = await tran2int(oldVer.split('.'));
int len = listNewVer.length;
for (int i = 0; i < len; i++) {
if (listNewVer[i] > listOldVer[i]) {
return true;
}
}
return false;
}
Future tran2int(List _list) async {
List listRet = [];
int len = _list.length;
for (int i = 0; i < len; i++) {
listRet.add(int.parse(_list[i].trim()));
}
return listRet;
}
///https://blog.csdn.net/zcylyzhi4/article/details/108002879
//5、自动更新代码
/// 执行版本更新的网络请求
/// 检查当前版本是否为最新,若不是,则更新
// void _checkVersionCode() {
// PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
// var currentVersionCode = packageInfo.version;
// if (double.parse(serviceVersionCode.substring(0, 3)) >
// double.parse(currentVersionCode.substring(0, 3))) {
// _showNewVersionAppDialog();
// }
// });
// }
}
+139
View File
@@ -0,0 +1,139 @@
import 'package:flutter/material.dart';
import '../../../components/commonFun.dart';
import '../../../widget/JdButton.dart';
import '../../../components/commonFun.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class MyAbout extends StatefulWidget {
MyAbout({Key key, this.ver, this.date}) : super(key: key);
String ver = '1.0.0';
String date = '';
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<MyAbout> {
var _username = new TextEditingController();
void initState() {
// TODO: implement initState
super.initState();
}
//监听登录页面销毁的事件
dispose() {
super.dispose();
}
doLogin() async {
//临时跳转
//Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
Navigator.pop(context); //返回
return;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("关于",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 5, right: 5),
child: ListView(
children: <Widget>[
Center(
child: Container(
margin: EdgeInsets.only(top: 30),
height: ScreenUtil().setWidth(160),
width: ScreenUtil().setWidth(160),
//child: Image.asset('assets/images/user.png', fit: BoxFit.cover),
child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
// child: Image.network(
// 'https://www.itying.com/images/flutter/list5.jpg',
// fit: BoxFit.cover),
),
),
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
SizedBox(height: 60),
Text('宜宾市黑烟车电子抓拍系统', style: TextStyle(fontSize: 20)),
Text('v${widget.ver}(${widget.date})', style: TextStyle(fontSize: 20)),
SizedBox(height: 60),
Text('© 宜宾市生态环境局 四川省踏石科技 版权所有\n服务热线:187-8467-8300',
maxLines: 2, style: TextStyle(fontSize: 16), textAlign: TextAlign.center),
],
),
),
SizedBox(height: 100),
Container(
padding: EdgeInsets.only(top: 20, bottom: 20, left: 20, right: 20),
child: JdButton(
height: 126,
text: "确认",
color: Colors.blueAccent,
onTop: doLogin,
),
),
],
),
),
);
}
}
+156
View File
@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import '../config/Config.dart';
import 'package:dio/dio.dart';
//订单列表数据模型
import '../model/OrderModel.dart';
import '../services/UserServices.dart';
import '../services/SignServices.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class OrderPage extends StatefulWidget {
OrderPage({Key key}) : super(key: key);
_OrderPageState createState() => _OrderPageState();
}
class _OrderPageState extends State<OrderPage> {
List _orderList = [];
@override
void initState() {
// TODO: implement initState
super.initState();
this._getListData();
}
void _getListData() async {
List userinfo = await UserServices.getUserInfo();
var tempJson = {"uid": userinfo[0]['_id'], "salt": userinfo[0]["salt"]};
var sign = SignServices.getSign(tempJson);
var api =
'${Config.domain}api/orderList?uid=${userinfo[0]['_id']}&sign=${sign}';
var response = await Dio().get(api);
print(response.data is Map);
setState(() {
var orderMode = new OrderModel.fromJson(response.data);
this._orderList = orderMode.result;
print(this._orderList[0].name);
});
}
//自定义商品列表组件
List<Widget> _orderItemWidget(orderItems) {
List<Widget> tempList = [];
for (var i = 0; i < orderItems.length; i++) {
tempList.add(Column(
children: <Widget>[
SizedBox(height: 10),
ListTile(
leading: Container(
width: ScreenUtil().setWidth(120),
height: ScreenUtil().setHeight(120),
child: Image.network(
'${orderItems[i].productImg}',
fit: BoxFit.cover,
),
),
title: Text("${orderItems[i].productTitle}"),
trailing: Text('x${orderItems[i].productCount}'),
),
SizedBox(height: 10)
],
));
}
return tempList;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("我的订单"),
),
body: Stack(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, ScreenUtil().setHeight(80), 0, 0),
padding: EdgeInsets.all(ScreenUtil().setWidth(16)),
child: ListView(
children: this._orderList.map((value) {
return InkWell(
onTap: (){
Navigator.pushNamed(context, '/orderinfo');
},
child: Card(
child: Column(
children: <Widget>[
ListTile(
title: Text("订单编号:${value.sId}",
style: TextStyle(color: Colors.black54)),
),
Divider(),
Column(
children: this._orderItemWidget(value.orderItem),
),
SizedBox(height: 10),
ListTile(
leading: Text("合计:¥${value.allPrice}"),
trailing: FlatButton(
child: Text("申请售后"),
onPressed: () {},
color: Colors.grey[100],
),
),
],
),
),
);
}).toList()),
),
Positioned(
top: 0,
width: ScreenUtil().setWidth(750),
height: ScreenUtil().setHeight(76),
child: Container(
width: ScreenUtil().setWidth(750),
height: ScreenUtil().setHeight(76),
color: Colors.white,
child: Row(
children: <Widget>[
Expanded(
child: Text("全部", textAlign: TextAlign.center),
),
Expanded(
child: Text("待付款", textAlign: TextAlign.center),
),
Expanded(
child: Text("待收货", textAlign: TextAlign.center),
),
Expanded(
child: Text("已完成", textAlign: TextAlign.center),
),
Expanded(
child: Text("已取消", textAlign: TextAlign.center),
)
],
),
),
)
],
),
);
}
}
+188
View File
@@ -0,0 +1,188 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class OrderInfoPage extends StatefulWidget {
OrderInfoPage({Key key}) : super(key: key);
_OrderInfoPageState createState() => _OrderInfoPageState();
}
class _OrderInfoPageState extends State<OrderInfoPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("订单详情")),
body: Container(
child: ListView(
children: <Widget>[
//收货地址
Container(
color: Colors.white,
child: Column(
children: <Widget>[
SizedBox(height: 10),
ListTile(
leading: Icon(Icons.add_location),
title: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("张三 15201686455"),
SizedBox(height: 10),
Text("北京市海淀区 西二旗"),
],
),
),
SizedBox(height: 10),
],
),
),
SizedBox(height: 16),
//列表
Container(
color: Colors.white,
padding: EdgeInsets.all(10),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
width: ScreenUtil().setWidth(120),
child: Image.network(
"https://www.itying.com/images/flutter/list2.jpg",
fit: BoxFit.cover),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("四季沐歌 (MICOE) 洗衣机水龙头 洗衣机水嘴 单冷快开铜材质龙头",
maxLines: 2,
style: TextStyle(color: Colors.black54)),
Text("水龙头 洗衣机",
maxLines: 2,
style: TextStyle(color: Colors.black54)),
ListTile(
leading: Text("¥100",
style: TextStyle(color: Colors.red)),
trailing: Text("x2"),
)
],
),
))
],
),
Row(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
width: ScreenUtil().setWidth(120),
child: Image.network(
"https://www.itying.com/images/flutter/list2.jpg",
fit: BoxFit.cover),
),
Expanded(
flex: 1,
child: Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 5),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("四季沐歌 (MICOE) 洗衣机水龙头 洗衣机水嘴 单冷快开铜材质龙头",
maxLines: 2,
style: TextStyle(color: Colors.black54)),
Text("水龙头 洗衣机",
maxLines: 2,
style: TextStyle(color: Colors.black54)),
ListTile(
leading: Text("¥100",
style: TextStyle(color: Colors.red)),
trailing: Text("x2"),
)
],
),
))
],
),
],
),
),
//详情信息
Container(
color: Colors.white,
margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Column(
children: <Widget>[
ListTile(
title: Row(
children: <Widget>[
Text("订单编号:",style: TextStyle(fontWeight: FontWeight.bold)),
Text("124215215xx324")
],
),
),
ListTile(
title: Row(
children: <Widget>[
Text("下单日期:",style: TextStyle(fontWeight: FontWeight.bold)),
Text("2019-12-09")
],
),
),
ListTile(
title: Row(
children: <Widget>[
Text("支付方式:",style: TextStyle(fontWeight: FontWeight.bold)),
Text("微信支付")
],
),
),
ListTile(
title: Row(
children: <Widget>[
Text("配送方式:",style: TextStyle(fontWeight: FontWeight.bold)),
Text("顺丰")
],
),
)
],
),
),
SizedBox(height: 16),
Container(
color: Colors.white,
margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
child: Column(
children: <Widget>[
ListTile(
title: Row(
children: <Widget>[
Text("总金额:",style: TextStyle(fontWeight: FontWeight.bold)),
Text("¥414元",style: TextStyle(
color: Colors.red
))
],
)
)
],
),
)
],
),
),
);
}
}
+74
View File
@@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import '../widget/JdButton.dart';
class PayPage extends StatefulWidget {
PayPage({Key key}) : super(key: key);
_PayPageState createState() => _PayPageState();
}
class _PayPageState extends State<PayPage> {
List payList = [
{
"title": "支付宝支付",
"chekced": true,
"image": "https://www.itying.com/themes/itying/images/alipay.png"
},
{
"title": "微信支付",
"chekced": false,
"image": "https://www.itying.com/themes/itying/images/weixinpay.png"
}
];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("去支付"),
),
body: Column(
children: <Widget>[
Container(
height: 400,
padding: EdgeInsets.all(20),
child: ListView.builder(
itemCount: this.payList.length,
itemBuilder: (context, index) {
return Column(
children: <Widget>[
ListTile(
leading:
Image.network("${this.payList[index]["image"]}"),
title: Text("${this.payList[index]["title"]}"),
trailing: this.payList[index]["chekced"]
? Icon(Icons.check)
: Text(""),
onTap: () {
//让payList里面的checked都等于false
setState(() {
for (var i = 0; i < this.payList.length; i++) {
this.payList[i]['chekced'] = false;
}
this.payList[index]["chekced"] = true;
});
},
),
Divider(),
],
);
},
)),
JdButton(
text: "支付",
color: Colors.red,
height: 74,
onTop: () {
print('支付1111');
},
)
],
),
);
}
}
+387
View File
@@ -0,0 +1,387 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import '../services/SearchServices.dart';
import '../config/Config.dart';
import 'package:dio/dio.dart';
import '../model/ProductModel.dart';
import '../widget/LoadingWidget.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class ProductListPage extends StatefulWidget {
Map arguments;
ProductListPage({Key key, this.arguments}) : super(key: key);
_ProductListPageState createState() => _ProductListPageState();
}
class _ProductListPageState extends State<ProductListPage> {
//Scaffold key
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
//用于上拉分页 listview 的控制器
ScrollController _scrollController = ScrollController();
//分页
int _page = 1;
//每页有多少条数据
int _pageSize = 8;
//数据
List _productList = [];
/*
排序:价格升序 sort=price_1 价格降序 sort=price_-1 销量升序 sort=salecount_1 销量降序 sort=salecount_-1
*/
String _sort = "";
//解决重复请求的问题
bool flag = true;
//是否有数据
bool _hasMore = true;
//是否有搜索的数据
bool _hasData = true;
/*二级导航数据*/
List _subHeaderList = [
{
"id": 1,
"title": "综合",
"fileds": "all",
"sort":
-1, //排序 升序:price_1 {price:1} 降序:price_-1 {price:-1}
},
{"id": 2, "title": "销量", "fileds": 'salecount', "sort": -1},
{"id": 3, "title": "价格", "fileds": 'price', "sort": -1},
{"id": 4, "title": "筛选"}
];
//二级导航选中判断
int _selectHeaderId = 1;
//配置search搜索框的值
var _initKeywordsController=new TextEditingController();
//cid
//keywords
var _cid;
var _keywords;
@override
void initState() {
super.initState();
this._cid=widget.arguments["cid"];
this._keywords=widget.arguments["keywords"];
//给search框框赋值
this._initKeywordsController.text=this._keywords;
_getProductListData();
//监听滚动条滚动事件
_scrollController.addListener(() {
//_scrollController.position.pixels //获取滚动条滚动的高度
//_scrollController.position.maxScrollExtent //获取页面高度
if (_scrollController.position.pixels >
_scrollController.position.maxScrollExtent - 20) {
if (this.flag && this._hasMore) {
_getProductListData();
}
}
});
}
//获取商品列表的数据
_getProductListData() async {
setState(() {
this.flag = false;
});
var api;
if(this._keywords==null){
api ='${Config.domain}api/plist?cid=${this._cid}&page=${this._page}&sort=${this._sort}&pageSize=${this._pageSize}';
}else{
api ='${Config.domain}api/plist?search=${this._keywords}&page=${this._page}&sort=${this._sort}&pageSize=${this._pageSize}';
}
// print(api);
var result = await Dio().get(api);
var productList = new ProductModel.fromJson(result.data);
//判断是否有搜索数据
if(productList.result.length==0 && this._page==1){
setState(() {
this._hasData=false;
});
}else{
this._hasData=true;
}
//判断最后一页有没有数据
if (productList.result.length < this._pageSize) {
setState(() {
this._productList.addAll(productList.result);
this._hasMore = false;
this.flag = true;
});
} else {
setState(() {
this._productList.addAll(productList.result);
this._page++;
this.flag = true;
});
}
}
//显示加载中的圈圈
Widget _showMore(index) {
if (this._hasMore) {
return (index == this._productList.length - 1)
? LoadingWidget() //显示加载中的圈圈
: Text("");
} else {
return (index == this._productList.length - 1)
? Text("--我是有底线的--")
: Text("");
;
}
}
//商品列表
Widget _productListWidget() {
if (this._productList.length > 0) {
return Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.only(top: ScreenUtil().setHeight(80)),
child: ListView.builder(
controller: _scrollController,
itemBuilder: (context, index) {
//处理图片
String pic = this._productList[index].pic;
pic = Config.domain + pic.replaceAll('\\', '/');
//每一个元素
return Column(
children: <Widget>[
Row(
children: <Widget>[
Container(
width: ScreenUtil().setWidth(180),
height: ScreenUtil().setHeight(180),
child: Image.network("${pic}", fit: BoxFit.cover),
),
Expanded(
flex: 1,
child: Container(
height: ScreenUtil().setHeight(180),
margin: EdgeInsets.only(left: 10),
// color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("${this._productList[index].num}",
maxLines: 2, overflow: TextOverflow.ellipsis),
Row(
children: <Widget>[
Container(
height: ScreenUtil().setHeight(36),
margin: EdgeInsets.only(right: 10),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
//注意 如果Container里面加上decoration属性,这个时候color属性必须得放在BoxDecoration
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromRGBO(230, 230, 230, 0.9),
),
child: Text("4g"),
),
Container(
height: ScreenUtil().setHeight(36),
margin: EdgeInsets.only(right: 10),
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(10),
color: Color.fromRGBO(230, 230, 230, 0.9),
),
child: Text("126"),
),
],
),
Text(
"¥${this._productList[index].price}",
style: TextStyle(color: Colors.red, fontSize: 16),
)
],
),
),
)
],
),
Divider(height: 20),
_showMore(index)
],
);
},
itemCount: this._productList.length,
),
);
} else {
//加载中
return LoadingWidget();
}
}
//导航改变的时候触发
_subHeaderChange(id) {
if (id == 4) {
_scaffoldKey.currentState.openEndDrawer();
setState(() {
this._selectHeaderId = id;
});
} else {
setState(() {
this._selectHeaderId = id;
this._sort ="${this._subHeaderList[id - 1]["fileds"]}_${this._subHeaderList[id - 1]["sort"]}";
//重置分页
this._page = 1;
//重置数据
this._productList = [];
//改变sort排序
this._subHeaderList[id - 1]['sort'] =
this._subHeaderList[id - 1]['sort'] * -1;
//回到顶部
_scrollController.jumpTo(0);
//重置_hasMore
this._hasMore = true;
//重新请求
this._getProductListData();
});
}
}
//显示header Icon
Widget _showIcon(id){
if(id==2|| id ==3){
if(this._subHeaderList[id-1]["sort"]==1){
return Icon(Icons.arrow_drop_down);
}
return Icon(Icons.arrow_drop_up);
}
return Text("");
}
//筛选导航
Widget _subHeaderWidget() {
return Positioned(
top: 0,
height: ScreenUtil().setHeight(80),
width: ScreenUtil().setWidth(750),
child: Container(
width: ScreenUtil().setWidth(750),
height: ScreenUtil().setHeight(80),
// color: Colors.red,
decoration: BoxDecoration(
border: Border(
bottom: BorderSide(
width: 1, color: Color.fromRGBO(233, 233, 233, 0.9)))),
child: Row(
children: this._subHeaderList.map((value) {
return Expanded(
flex: 1,
child: InkWell(
child: Padding(
padding: EdgeInsets.fromLTRB(
0, ScreenUtil().setHeight(16), 0, ScreenUtil().setHeight(16)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
"${value["title"]}",
textAlign: TextAlign.center,
style: TextStyle(
color: (this._selectHeaderId == value["id"])
? Colors.red
: Colors.black54),
),
_showIcon(value["id"])
],
),
),
onTap: () {
_subHeaderChange(value["id"]);
},
),
);
}).toList(),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
key: _scaffoldKey,
appBar:AppBar(
title: Container(
child: TextField(
controller: this._initKeywordsController,
autofocus: false,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none)),
onChanged: (value){
setState(() {
this._keywords=value;
});
},
),
height: ScreenUtil().setHeight(68),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.8),
borderRadius: BorderRadius.circular(30)),
),
actions: <Widget>[
InkWell(
child: Container(
height: ScreenUtil().setHeight(68),
width: ScreenUtil().setWidth(80),
child: Row(
children: <Widget>[Text("搜索")],
),
),
onTap: () {
SearchServices.setHistoryData(this._keywords);
this._subHeaderChange(1);
},
)
],
),
endDrawer: Drawer(
child: Container(
child: Text("实现筛选功能"),
),
),
body: _hasData?Stack(
children: <Widget>[
_productListWidget(),
_subHeaderWidget(),
],
):Center(
child: Text("没有您要浏览的数据")
)
);
}
}
+80
View File
@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
import '../widget/JdText.dart';
import '../widget/JdButton.dart';
import '../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class RegisterFirstPage extends StatefulWidget {
RegisterFirstPage({Key key}) : super(key: key);
_RegisterFirstPageState createState() => _RegisterFirstPageState();
}
class _RegisterFirstPageState extends State<RegisterFirstPage> {
String tel="";
sendCode() async {
RegExp reg = new RegExp(r"^1\d{10}$");
if (reg.hasMatch(this.tel)) {
var api = '${Config.domain}api/sendCode';
var response = await Dio().post(api, data: {"tel": this.tel});
if (response.data["success"]) {
print(response); //演示期间服务器直接返回 给手机发送的验证码
Navigator.pushNamed(context, '/registerSecond', arguments: {
"tel":this.tel
});
} else {
Fluttertoast.showToast(
msg: '${response.data["message"]}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
} else {
Fluttertoast.showToast(
msg: '手机号格式不对',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("用户注册-第一步"),
),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
SizedBox(height: 50),
JdText(
height: ScreenUtil().setHeight(300),
text: "请输入手机号",
onChanged: (value) {
// print(value);
this.tel = value;
},
),
SizedBox(height: 20),
JdButton(
height: ScreenUtil().setHeight(350),
text: "下一步",
color: Colors.red,
onTop: sendCode,
)
],
),
),
);
}
}
+139
View File
@@ -0,0 +1,139 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../widget/JdText.dart';
import '../widget/JdButton.dart';
import 'dart:async'; //Timer定时器需要引入
import '../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class RegisterSecondPage extends StatefulWidget {
Map arguments;
RegisterSecondPage({Key key, this.arguments}) : super(key: key);
_RegisterSecondPageState createState() => _RegisterSecondPageState();
}
class _RegisterSecondPageState extends State<RegisterSecondPage> {
String tel;
bool sendCodeBtn = false;
int seconds = 10;
String code;
@override
void initState() {
// TODO: implement initState
super.initState();
this.tel = widget.arguments['tel'];
this._showTimer();
}
//倒计时
_showTimer() {
Timer t;
t = Timer.periodic(Duration(milliseconds: 1000), (timer) {
setState(() {
this.seconds--;
});
if (this.seconds == 0) {
t.cancel(); //清除定时器
setState(() {
this.sendCodeBtn = true;
});
}
});
}
//重新发送验证码
sendCode() async {
setState(() {
this.sendCodeBtn = false;
this.seconds = 10;
this._showTimer();
});
var api = '${Config.domain}api/sendCode';
var response = await Dio().post(api, data: {"tel": this.tel});
if (response.data["success"]) {
print(response); //演示期间服务器直接返回 给手机发送的验证码
}
}
//验证验证码
validateCode() async {
var api = '${Config.domain}api/validateCode';
var response =
await Dio().post(api, data: {"tel": this.tel, "code": this.code});
if (response.data["success"]) {
Navigator.pushNamed(context, '/registerThird',arguments: {
"tel":this.tel,
"code":this.code
});
} else {
Fluttertoast.showToast(
msg: '${response.data["message"]}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("用户注册-第二步"),
),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
SizedBox(height: 50),
Container(
padding: EdgeInsets.only(left: 10),
child: Text("验证码已经发送到了您的${this.tel}手机,请输入${this.tel}手机号收到的验证码"),
),
SizedBox(height: 40),
Stack(
children: <Widget>[
Container(
child: JdText(
text: "请输入验证码",
onChanged: (value) {
// print(value);
this.code = value;
},
),
height: ScreenUtil().setHeight(150),
),
Positioned(
right: 0,
top: 0,
child: this.sendCodeBtn
? RaisedButton(
child: Text('重新发送'),
onPressed: this.sendCode,
)
: RaisedButton(
child: Text('${this.seconds}秒后重发'),
onPressed: () {},
),
)
],
),
SizedBox(height: 20),
JdButton(
height: ScreenUtil().setHeight(350),
text: "下一步",
color: Colors.red,
onTop: this.validateCode,
)
],
),
),
);
}
}
+117
View File
@@ -0,0 +1,117 @@
import 'package:flutter/material.dart';
import '../widget/JdText.dart';
import '../widget/JdButton.dart';
import '../config/Config.dart';
import 'package:dio/dio.dart';
import 'package:fluttertoast/fluttertoast.dart';
import '../services/Storage.dart';
import 'dart:convert';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//引入Tabs
import '../pages/tabs/Tabs.dart';
class RegisterThirdPage extends StatefulWidget {
Map arguments;
RegisterThirdPage({Key key, this.arguments}) : super(key: key);
_RegisterThirdPageState createState() => _RegisterThirdPageState();
}
class _RegisterThirdPageState extends State<RegisterThirdPage> {
String tel;
String code;
String password = '';
String rpassword = '';
@override
void initState() {
// TODO: implement initState
super.initState();
this.tel = widget.arguments["tel"];
this.code = widget.arguments["code"];
}
//注册
doRegister() async {
if (password.length < 6) {
Fluttertoast.showToast(
msg: '密码长度不能小于6位',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else if (rpassword != password) {
Fluttertoast.showToast(
msg: '密码和确认密码不一致',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
} else {
var api = '${Config.domain}api/register';
var response = await Dio().post(api, data: {"tel": this.tel, "code": this.code, "password": this.password});
if (response.data["success"]) {
//保存用户信息
Storage.setString('userInfo', json.encode(response.data["userinfo"]));
//返回到根
// Navigator.of(context)
// .pushAndRemoveUntil(new MaterialPageRoute(builder: (context) => new Tabs()), (route) => route == null);
//临时跳转
Navigator.pushNamed(context, '/', arguments: 1);
} else {
Fluttertoast.showToast(
msg: '${response.data["message"]}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("用户注册-第三步"),
),
body: Container(
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView(
children: <Widget>[
SizedBox(height: 50),
JdText(
height: ScreenUtil().setHeight(300),
text: "请输入密码",
password: true,
onChanged: (value) {
this.password = value;
},
),
SizedBox(height: 10),
JdText(
height: ScreenUtil().setHeight(300),
text: "请输入确认密码",
password: true,
onChanged: (value) {
this.rpassword = value;
},
),
SizedBox(height: 20),
JdButton(
text: "注册",
color: Colors.red,
height: ScreenUtil().setHeight(350),
onTop: doRegister,
)
],
),
),
);
}
}
+235
View File
@@ -0,0 +1,235 @@
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import '../services/SearchServices.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class SearchPage extends StatefulWidget {
SearchPage({Key key}) : super(key: key);
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
var _keywords;
List _historyListData = [];
@override
void initState() {
super.initState();
this._getHistoryData();
}
_getHistoryData() async {
var _historyListData = await SearchServices.getHistoryList();
setState(() {
this._historyListData=_historyListData;
});
}
_showAlertDialog(keywords) async{
var result= await showDialog(
barrierDismissible:false, //表示点击灰色背景的时候是否消失弹出框
context:context,
builder: (context){
return AlertDialog(
title: Text("提示信息!"),
content:Text("您确定要删除吗?") ,
actions: <Widget>[
FlatButton(
child: Text("取消"),
onPressed: (){
print("取消");
Navigator.pop(context,'Cancle');
},
),
FlatButton(
child: Text("确定"),
onPressed: () async{
//注意异步
await SearchServices.removeHistoryData(keywords);
this._getHistoryData();
Navigator.pop(context,"Ok");
},
)
],
);
}
);
// print(result);
}
Widget _historyListWidget() {
if (_historyListData.length > 0) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
child: Text("历史记录", style: Theme.of(context).textTheme.title),
),
Divider(),
Column(
children: this._historyListData.map((value) {
return Column(
children: <Widget>[
ListTile(
title: Text("${value}"),
onLongPress: (){
this._showAlertDialog("${value}");
},
),
Divider()
],
);
}).toList(),
),
SizedBox(height: 100),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
InkWell(
onTap: () {
SearchServices.clearHistoryList();
this._getHistoryData();
},
child: Container(
width: ScreenUtil().setWidth(400),
height: ScreenUtil().setHeight(64),
decoration: BoxDecoration(
border: Border.all(color: Colors.black45, width: 1)),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[Icon(Icons.delete), Text("清空历史记录")],
),
),
)
],
)
],
);
} else {
return Text("");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Container(
child: TextField(
autofocus: true,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(30),
borderSide: BorderSide.none)),
onChanged: (value) {
this._keywords = value;
},
),
height: ScreenUtil().setHeight(68),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.8),
borderRadius: BorderRadius.circular(30)),
),
actions: <Widget>[
InkWell(
child: Container(
height: ScreenUtil().setHeight(68),
width: ScreenUtil().setWidth(80),
child: Row(
children: <Widget>[Text("搜索")],
),
),
onTap: () {
SearchServices.setHistoryData(this._keywords);
Navigator.pushReplacementNamed(context, '/productList',
arguments: {"keywords": this._keywords});
},
)
],
),
body: Container(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
child: Text("热搜", style: Theme.of(context).textTheme.title),
),
Divider(),
Wrap(
children: <Widget>[
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("笔记本电脑"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装111"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装"),
),
Container(
padding: EdgeInsets.all(10),
margin: EdgeInsets.all(10),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.9),
borderRadius: BorderRadius.circular(10)),
child: Text("女装"),
)
],
),
SizedBox(height: 10),
//历史记录
_historyListWidget()
],
),
));
}
}
+514
View File
@@ -0,0 +1,514 @@
import 'package:flutter/material.dart';
import 'package:flutter_bmfbase/BaiduMap/bmfmap_base.dart';
import 'package:flutter_bmfmap/BaiduMap/bmfmap_map.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
import '../../../components/dioFun.dart';
import 'dwInfoDialog.dart';
import 'dwInfo_data.dart';
class BasicMap extends StatefulWidget {
BasicMap({this.hyshlx = 'dwdt', this.title = "点位地图"});
String hyshlx;
String title;
@override
_BasicMapState createState() => _BasicMapState();
}
class _BasicMapState extends State<BasicMap> {
Size screenSize;
BMFMapOptions mapOptions;
BMFMapController myMapController;
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void initState() {
super.initState();
mapOptions = BMFMapOptions(
//center: BMFCoordinate(39.965, 116.404),//北京市
//30 116.395645038,39.9299857781 北京-北京市
//center: BMFCoordinate(34.263161, 108.948024), //西安市
/// 设置地图显示中心点坐标,必须是百度官方发布的百度地图-城市中心点坐标
/// 为宜宾市白塔山: BMFCoordinate(104.644079, 28.77914)
//center: BMFCoordinate(104.644079, 28.77914), //宜宾市白塔山,无效,经纬度搞反了
//52 104.633019062,28.7696747963 四川省-宜宾市
///Flutter百度地图采坑注意:
// BMFCoordinate(this.latitude, this.longitude);
// BMFCoordinate 构造方法参数是纬度在前、经度在后,latitude 纬度,longitude 经度
// 百度官方发布的城市中心点坐标是经度在前、纬度在后,必须对调才行,否则无法正确显示指定城市的地图
// 比如://52 104.633019062,28.7696747963 四川省-宜宾市
// 必须将经纬度对调才行:center: BMFCoordinate(28.7696747963, 104.633019062), //四川省-宜宾市
//center: BMFCoordinate(28.7696747963, 104.633019062), //四川省-宜宾市
center: BMFCoordinate(28.77914, 104.644079),
//宜宾市白塔山
//宜宾市白塔山
showMapPoi: _showMapPoi,
//设定地图是否显示底图poi标注(不包含室内图标注),默认true
zoomLevel: g_zoomLevel,
maxZoomLevel: 16,
minZoomLevel: 12,
mapPadding: BMFEdgeInsets(left: 30, top: 0, right: 30, bottom: 0),
//showMapScaleBar: true,
);
iPage = 0;
listDwspGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList(theHyshlx: widget.hyshlx, bShowToast: false).then((value) async {
//mapHyshlx[hyshlx]['api'];
listDwspGetList2 = value;
listDwinfoGetList2 = value;
//try_setState();
//按照用户选择的_selectedValue、_descending对listDwspGetList2进行排序,并延时更新
// int len = listDwspGetList2.length;
// for (int i = 0; i < len; i++) {
// getDwspUrl(index: listDwspGetList2[i]['id']).then((value) {
// listDwspGetList2[i]['dwsp_ok'] = true;
// if (value == '' || value == null) {
// listDwspGetList2[i]['dwsp_ok'] = false;
// }
// setState(() {});
// });
// }
});
//为播放点位视频读取数据
//在 Page1_Works 页面,获取 startGetStatisData() 时,便已经获取了 listDwinfoGetList2
// ///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
// getPageList(theHyshlx: 'dwxx', bShowToast: false).then((value) async {
// //mapHyshlx[hyshlx]['api'];
// listDwspGetList2 = value;
//
// //按_selectedValue排序,升序
// listDwspGetList2
// .sort((a, b) => (a[mapWzxxDataText['点位编号']]).compareTo(b[mapWzxxDataText['点位编号']]));
// });
}
//设定地图是否显示底图poi标注(不包含室内图标注),默认true
bool _showMapPoi = true;
/// 创建完成回调
void onBMFMapCreated(BMFMapController controller) async {
myMapController = controller;
/// 设置地图状态改变完成后回调接口
myMapController?.setMapStatusDidChangedCallback(callback: () {
myMapController.getZoomLevel().then((zoomLevel) {
print('Current zoomLevel = $zoomLevel');
g_zoomLevel = zoomLevel; //缩放倍数
getListBMFMarker().then((value) async {
///先清除地图上的所有Marker
await myMapController?.removeMarkers(g_listBMFMarker);
///批量添加定位标记
await myMapController?.addMarkers(g_listBMFMarker);
///批量添加文字标记,作为定位标记的说明文字
for (var text in g_listBMFText) {
//text.setMethodChannel(MethodChannel());
await myMapController?.addText(text);
}
//加在此处无效
//点击Marker时会回调BaiduMap.OnMarkerClickListener,监听器的实现方式示例如下:
/// 地图marker点击回调
//myMapController?.setMapClickedMarkerCallback(callback: _markerCallback);
});
setState(() {});
});
});
/// 地图加载回调
myMapController?.setMapDidLoadCallback(callback: () {
print('mapDidLoad-地图加载完成');
});
///批量添加定位标记
getListBMFMarker().then((value) {
myMapController?.addMarkers(g_listBMFMarker);
///批量添加文字标记,作为定位标记的说明文字
for (var text in g_listBMFText) {
myMapController?.addText(text);
}
///1、底图标注 点击回调:
// 点中底图标注后会回调此接口
myMapController?.setMapOnClickedMapPoiCallback(callback: (BMFMapPoi mapPoi) async {
print('mapPoi = ${mapPoi.toMap().toString()}');
myMapController.getZoomLevel().then((value) {
g_zoomLevel = value;
print('myMapController.getZoomLevel() = ${value.toString()}');
});
//I/flutter (11895): mapPoi = {text: 森林小区, pt: {latitude: 28.765632464539106, longitude: 104.60481101089357}, uid: ea4cae6307501c5f4d2fdfe9}
onMarkerClicked(mapPoi.pt);
});
///2、底图空白处 点击回调
// 点中底图空白处会回调此接口
/// coordinate 经纬度
myMapController?.setMapOnClickedMapBlankCallback(callback: (BMFCoordinate coordinate) {
print('点击底图空白处响应:coordinate = ${coordinate.toMap().toString()}');
myMapController.getZoomLevel().then((value) {
g_zoomLevel = value;
print('myMapController.getZoomLevel() = ${value.toString()}');
});
onMarkerClicked(coordinate);
});
//3、Marker 点击响应,点击文本标签没反应,加在此处有效
//点击Marker时会回调BaiduMap.OnMarkerClickListener,监听器的实现方式示例如下:
/// 地图marker点击回调
myMapController?.setMapClickedMarkerCallback(callback: (String id, dynamic extra) async {
myMapController.getZoomLevel().then((value) {
g_zoomLevel = value;
print('myMapController.getZoomLevel() = ${value.toString()}');
});
print('点击 Marker 标签响应:id = ${id}');
//百度地图的脑残设计,需要在添加BMFMarker时自己保存ID
//g_listBMFMarkerIDmap.add({marker.getId(): listDwinfo[i]["id"]});
print('Marker的 标签响应:id = ${listDwinfoGetList2[g_map_BMFMarkerID_dwIndex[id]]["dwmc"]}');
_markerCallback(id, 'test'); //响应用户点击
});
});
//批量添加定位标记
}
Map mapBMFTextCoordinateList = {};
//1、江北振兴大道 估算坐标区域
// 左上角 coordinate = {latitude: 28.807221307340154, longitude: 104.60667948635371}
// 右下角 coordinate = {latitude: 28.805069070677582, longitude: 104.62110627283919}
// listMarkerCoordinate是包含13个Map点位标记的List,每个Map元素包括4个子元素,
// 分别是左上角坐标(纬度 latitude,经度 longitude)、右下角坐标(纬度 latitude,经度 longitude)
List listMarkerCoordinate1 = [
{
'topLatitude': 28.807221307340154,
'leftLongitude': 104.60667948635371,
'bottomLatitude': 28.805069070677582,
'rightLongitude': 104.62110627283919
}
];
//12、大麦坝
//左上角 coordinate = coordinate = {latitude: 28.8044360513459, longitude: 104.63110441316194}
//右下角 coordinate = coordinate = {latitude: 28.803415299489192, longitude: 104.63598221207951}
// listMarkerCoordinate是包含13个Map点位标记的List,每个Map元素包括4个子元素,
// 分别是左上角坐标(纬度 latitude,经度 longitude)、右下角坐标(纬度 latitude,经度 longitude)
//15倍放大时设置,地图放到18倍时,点击没有问题,
//缩小到13倍时,不行了
//15倍放大
//左下角coordinate = {latitude: 28.79913436190729, longitude: 104.66847392236468}
//左上角coordinate = {latitude: 28.806612039019615, longitude: 104.62731356391107}
List listMarkerCoordinate = [
{
'topLatitude': 28.80778309701711,
'leftLongitude': 104.63028695514814,
'bottomLatitude': 28.79801859852449,
'rightLongitude': 104.66974951618843
}
];
//以13倍放大时的数据设置
//左下角coordinate = {latitude: 28.80399293550177, longitude: 104.63028695514814}
//左上角coordinate = {latitude: 28.79801859852449, longitude: 104.66974951618843}
// 中国在世界地图上的经纬度范围? // 2019-04-14 · 把复杂的事情简单说给你听
// top 北起黑龙江省漠河以北的黑龙江主航道的中心线 北纬 53°31′
// bottom 南达南海南沙群岛的曾母内暗沙 北纬 4°15′
// left 西起新容疆维吾尔自治区乌恰县以西的帕米尔高原 东经 73°
// right 东至黑龙江省抚远县境内的黑龙江与乌苏里江汇合处 东经 135°。
//
// 中国位于地球的东半球北半部、亚欧大陆的东南部、亚洲的东部和中部、太平洋的西岸。
int i = 0;
//纬度 latitude,经度 longitude
Future onMarkerClicked(BMFCoordinate coordinate) {
//double scale = g_zoomLevel / 15;
if (listMarkerCoordinate[i]['topLatitude'] > coordinate.latitude &&
coordinate.latitude > listMarkerCoordinate[i]['bottomLatitude'] &&
listMarkerCoordinate[i]['rightLongitude'] > coordinate.longitude &&
coordinate.longitude > listMarkerCoordinate[i]['leftLongitude']) {
_markerCallback('123', 'test');
} //响应用户点击
}
bool isDoing = false;
Future _markerCallback(String id, dynamic extra) async {
if (isDoing) {
print('正在处理中...,不能重复进入');
return;
}
print('开始处理');
print('mapClickedMarker--\n marker = $id');
//已经能够弹出Flutter对话框。但只有点击 Marker 标签有反应,点击文本标签没反应。
//百度地图的脑残设计,需要在添加BMFMarker时自己保存ID
//g_listBMFMarkerIDmap.add({marker.getId(): listDwinfo[i]["id"]});
int dwIndex = g_map_BMFMarkerID_dwIndex[id];
print('Marker的 标签响应:id = ${listDwinfoGetList2[dwIndex]["dwmc"]}');
getStatisData(statisType: 'zptj', ip: listDwinfoGetList2[dwIndex]['dwip'])
.then((mapStatisData) async {
String title =
listDwinfoGetList2[dwIndex]["id"].toString() + '、' + listDwinfoGetList2[dwIndex]["dwmc"];
List listCoordinate = listDwinfoGetList2[dwIndex]["dwzb"].trim().split('|');
String content = listDwinfoGetList2[dwIndex]["dwms"] +
'。\n经度:${listCoordinate[0]}\n纬度:${listCoordinate[1]}' +
'\n今日抓拍:${mapStatisData['today']['total']}, 累计抓拍:${mapStatisData['all']}' +
'\n运行状态:${listDwinfoGetList2[dwIndex]['dwzt']}';
await Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
dwInfoDialog(id: id, dwIndex: dwIndex, title: title, content: content),
),
)
.then((value) async {
print('value = $value');
if (value) {
print('用户已确认,开始处理推送交警!');
//return;
} else {
print('用户取消了推送交警操作');
}
});
setState(() {
// _markerID = id;
// _action = "点击";
});
isDoing = false;
});
}
double _widthBtn = 45;
double _heightBtn = 45;
double _edge = 16;
@override
Widget build(BuildContext context) {
screenSize = MediaQuery.of(context).size;
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(widget.title + '(${g_zoomLevel}倍)',
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 10),
],
),
actions: <Widget>[
Row(
children: [
//SizedBox(width: ScreenUtil().setWidth(45)),
InkWell(
onTap: () {
//Navigator.pushNamed(context, '/registerFirst');
this.setState(() {
_showMapPoi = !_showMapPoi;
myMapController?.updateMapOptions(BMFMapOptions(showMapPoi: _showMapPoi));
});
},
child: Container(
alignment: Alignment(0, 0),
//width: 150,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('标注:', style: TextStyle(fontSize: 20, color: Colors.white)),
Container(
alignment: Alignment(0, 0),
height: 25,
width: 25,
padding: EdgeInsets.only(top: ScreenUtil().setHeight(6)),
child: _showMapPoi
? Icon(Icons.check_box, color: Colors.white)
: Icon(Icons.check_box_outline_blank, color: Colors.white),
),
SizedBox(width: ScreenUtil().setWidth(65)),
],
),
),
),
],
),
],
),
),
body: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(
height: screenSize.height,
width: screenSize.width,
child: BMFMapWidget(
onBMFMapCreated: (controller) {
onBMFMapCreated(controller);
},
mapOptions: mapOptions,
),
),
),
Align(
alignment: Alignment(1, 1),
child: Padding(
padding: EdgeInsets.only(bottom: 5, right: _edge),
child: Container(
width: _widthBtn,
height: _heightBtn * 2 + 3,
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(2.0)),
border: new Border.all(width: 1, color: Colors.blue),
),
child: Column(
children: [
Container(
width: _widthBtn,
height: _heightBtn,
//color: Colors.white,
child: InkWell(
// child: Icon(Icons.my_location_outlined, color: Colors.black45),
child: Icon(Icons.add, color: g_zoomLevel < 16 ? Colors.blue : Colors.grey),
onTap: g_zoomLevel < 16
? () {
//放大按钮,缩放限制12-16
if (g_zoomLevel < 16) {
g_zoomLevel++;
myMapController
?.updateMapOptions(BMFMapOptions(zoomLevel: g_zoomLevel));
}
}
: null,
),
),
Divider(height: 1.0, color: Colors.blue),
Container(
width: _widthBtn,
height: _heightBtn,
//color: Colors.white,
child: InkWell(
// child: Icon(Icons.my_location_outlined, color: Colors.black45),
child: Icon(Icons.horizontal_rule,
color: g_zoomLevel > 12 ? Colors.blue : Colors.grey),
onTap: g_zoomLevel > 12
? () {
//缩小按钮,缩放限制12-16
g_zoomLevel--;
myMapController
?.updateMapOptions(BMFMapOptions(zoomLevel: g_zoomLevel));
}
: null,
),
),
],
),
),
),
),
Align(
alignment: Alignment(-1, 1),
child: Padding(
padding: EdgeInsets.only(bottom: 50, left: _edge),
child: Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(2.0)),
border: new Border.all(width: 1, color: Colors.blue),
),
width: _widthBtn,
height: _heightBtn,
//color: Colors.white,
child: InkWell(
// child: Icon(Icons.my_location_outlined, color: Colors.black45),
// 没有
child: Icon(Icons.radio_button_checked_rounded,
color: g_zoomLevel == 14 ? Colors.grey : Colors.blue),
onTap: () {
g_zoomLevel = 14;
//还原按钮,重新设置中心位置、缩放级别
//myMapController.setCenterCoordinate(coordinate, animated);
//没有myMapController.getCenterCoordinate,无法简单地获取当前中心坐标;
myMapController?.updateMapOptions(
BMFMapOptions(center: BMFCoordinate(28.77914, 104.644079)));
myMapController?.updateMapOptions(BMFMapOptions(zoomLevel: g_zoomLevel));
},
),
),
),
),
],
),
);
}
}
+118
View File
@@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
//import 'package:hyzp_ybqx/widget/player_pro.dart';
import '../../../components/commonFun.dart';
//确认对话框
class dwInfoDialog extends Dialog {
dwInfoDialog({@required this.id, this.title = "", @required this.dwIndex, this.content});
int dwIndex;
String id;
String title;
String content;
bool ret = false;
@override
Widget build(BuildContext context) {
Size mediaSize = MediaQuery.of(context).size;
return WillPopScope(
child: Material(
type: MaterialType.transparency,
child: Container(
padding: EdgeInsets.only(top: 116),
alignment: Alignment(0, -1),
color: Colors.black12,
child: Container(
// height: 260,
// width: 300,
height: mediaSize.height * 0.51,
width: mediaSize.width * 0.95,
//color: Colors.white, //Cannot provide both a color and a decoration
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.blue, width: 2.0),
borderRadius: BorderRadius.all(
Radius.circular(5),
),
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Text(
"${this.title}",
style: TextStyle(
fontSize: 20.0,
),
),
),
Align(
alignment: Alignment.centerRight,
child: InkWell(
child: Icon(Icons.close),
onTap: () {
getingDwVideo = false;
Navigator.pop(context, ret);
},
),
)
],
),
),
Divider(color: Colors.blue),
Container(
padding: EdgeInsets.fromLTRB(20, 10, 20, 10),
width: double.infinity,
height: mediaSize.height * 0.28,
child: SingleChildScrollView(
child: Text(content, style: TextStyle(fontSize: 18.0, color: Colors.blue)),
),
),
SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
RaisedButton(
onPressed: () {
ret = true;
//getDwspUrl(index: dwIndex, context: context);
getDwspUrlNew(indexRecord: dwIndex, context: context);
},
child: Text("视频"),
),
RaisedButton(
onPressed: () async {
ret = true;
getingDwVideo = false;
Navigator.pop(context, ret); //关闭弹框,返回sRet
},
child: Text("确认"),
),
RaisedButton(
child: Text("取消"),
onPressed: () async {
getingDwVideo = false;
Navigator.pop(context, ret); //关闭弹框,返回sRet
},
)
],
),
],
),
),
),
),
onWillPop: () {
// 屏蔽点击返回键的操作
getingDwVideo = false;
Navigator.pop(context, ret);
},
);
}
}
+120
View File
@@ -0,0 +1,120 @@
import 'package:flutter/material.dart';
import 'package:flutter_bmfbase/BaiduMap/bmfmap_base.dart';
import 'package:flutter_bmfmap/BaiduMap/bmfmap_map.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
///批量添加定位标记
bool enable = true;
bool dragable = true;
int g_zoomLevel = 14; //缩放倍数
///批量添加定位标记
List<BMFMarker> g_listBMFMarker = [];
Map g_map_BMFMarkerID_dwIndex = {};
List<BMFText> g_listBMFText = [];
//https://www.cnblogs.com/ybmj/p/14408263.html
//百度地图的脑残设计,附上代码,为后来的码农们...
Future getListBMFMarker({List listDwinfo}) async {
if (null == listDwinfo) {
listDwinfo = listDwinfoGetList2;
}
//double _scale = 9900 / 10000; //自己控制off_latitude、off_longitude效果不好
// BMFMarker marker1 = BMFMarker(
// position: BMFCoordinate(28.807061, 104.607091),
// title: '1、江北振兴大道',
// subtitle: 'test',
// identifier: 'flutter_marker',
// icon: 'assets/images/location.png',
// enabled: enable,
// draggable: dragable);
int len = listDwinfo.length;
for (int i = 0; i < len; i++) {
BMFMarker marker = BMFMarker(
position: getBMFCoordinate(listDwinfo[i]["dwzb"]),
title: '${listDwinfo[i]["id"].toString()}、${listDwinfo[i]["dwmc"]}',
subtitle: 'test',
identifier: '${listDwinfo[i]["id"].toString()}、${listDwinfo[i]["dwmc"]}',
icon: 'assets/images/location.png',
/// 默认情况下, annotation view的中心位于annotation的坐标位置,
/// 可以设置centerOffset改变view的位置,正的偏移使view朝右下方移动,负的朝左上方,单位是像素
/// 目前Android只支持Y轴设置偏移量对应SDK的 yOffset(int yOffset) 方法
/// 添加标记 BMFMarker 百度官方有 centerOffset 偏移参数,
/// 文本标签 BMFText 官方没有 centerOffset 偏移参数,我取消了 BMFMarker 的偏移。你看这样行吗?
/// 按公司要求,为更准确定位,取消 BMFMarker 的偏移
centerOffset: BMFPoint(0, 0),
//标记中心偏移
enabled: enable,
draggable: dragable);
// 百度地图的脑残设计,用Flutter添加多个BMFMarker时,必须在添加BMFMarker时自己保存ID,
// 否则响应点击时无法确定用户点击的是哪个定位标注
// 代码不会自动返回,也没有任何文档说明,是花了一天时间搜索网络无果,是自己翻江倒海摸索出来的
// 下一句是关键代码,将添加的每个BMFMarker的id保存到一个map中,
// 这样在用setMapClickedMarkerCallback添加BMFMarker的通用响应函数中,便可以根据id号来判断用户点击的是哪一个定位标注
g_map_BMFMarkerID_dwIndex[marker.getId()] = i;
g_listBMFMarker.add(marker);
g_listBMFText.add(BMFText(
text: '${listDwinfo[i]["id"].toString()}、${listDwinfo[i]["dwmc"]}',
//纬度偏移-上下 off_latitude, 经度偏移-左右 off_longitude
//已经在zoomLevel = 15时调整好定位标记与文本标记的相对位置
// ,当地图缩放时,会发生位置变化,必须使用 Provider 或者 EventBus 进行跟踪更新
//https://time.geekbang.org/column/article/131890
//老师,provider、eventBus的用途有啥区别吗,都可以做状态的通知
// 作者回复: Provider 主要是用来做数据读写共享;event_bus主要是用来做数据状态通知、实现组件间单向数据传递。
//如果我们的应用足够简单,数据流动的方向和顺序是清晰的,我们只需要将数据映射成视图就可以了。
// 作为声明式的框架,Flutter 可以自动处理数据到渲染的全过程,通常并不需要 Provider 状态管理。
// position: getBMFCoordinate(listDwinfo[i]["dwzb"],
// off_latitude: -0.0002 * g_zoomLevel * _scale,
// off_longitude: -0.00009 * g_zoomLevel * _scale),
position: getBMFCoordinate(listDwinfo[i]["dwzb"]),
//自己控制off_latitude、off_longitude效果不好
bgColor: Colors.yellow,
fontColor: Colors.black,
fontSize: 35,
// typeFace:
// BMFTypeFace(familyName: BMFFamilyName.sMonospace, textStype: BMFTextStyle.BOLD_ITALIC),
typeFace: BMFTypeFace(familyName: BMFFamilyName.sMonospace, textStype: BMFTextStyle.BOLD),
alignY: BMFVerticalAlign.ALIGN_TOP,
alignX: BMFHorizontalAlign.ALIGN_LEFT,
rotate: 0.0,
zIndex: 99));
}
}
//文字覆盖物
// 文字(Text)在地图上也是一种覆盖物,由BMFText类定义,示例代码如下:
//
// /// text经纬度信息
// BMFCoordinate position = new BMFCoordinate(39.73235, 116.350338);
//
// /// 构造text
// BMFText bmfText = BMFText(
// text: 'hello world',
// position: position,
// bgColor: Colors.blue,
// fontColor: Colors.red,
// fontSize: 40,
// typeFace: BMFTypeFace( familyName: BMFFamilyName.sMonospace,
// textStype: BMFTextStyle.BOLD_ITALIC),
// alignY: BMFVerticalAlign.ALIGN_TOP,
// alignX: BMFHorizontalAlign.ALIGN_LEFT,
// rotate: 30.0);
//
// /// 添加text
// myMapController.addText(bmfText);
//从"dwzb": "104.607091|28.807061",得到BMFCoordinate(28.807061, 104.607091)
//纬度偏移-上下 off_latitude, 经度偏移-左右 off_longitude
//自己控制off_latitude、off_longitude效果不好
BMFCoordinate getBMFCoordinate(String dwzb, {double off_latitude = 0, double off_longitude = 0}) {
off_latitude = 0; //取消偏移
off_longitude = 0; //取消偏移
List _listCoordinateItem = dwzb.trim().split('|');
return BMFCoordinate(double.parse(_listCoordinateItem[1]) - off_latitude,
double.parse(_listCoordinateItem[0]) - off_longitude);
}
+567
View File
@@ -0,0 +1,567 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/widget/my_delay_toast.dart';
import '../../../components/commonFun.dart';
//import 'package:hyzp_ybqx/widget/player_pro.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../services/EventBus.dart';
//dwsp是本项目中“点位视频”的统一缩写
class DwspGetList extends StatefulWidget {
//hyshlx为黑烟审核类型,处理dwsp信息。mapHyshlx[hyshlx]获取为各种类型的设置数据
DwspGetList({this.hyshlx = 'dwxx', Key key}) : super(key: key);
String hyshlx;
_DwspPageState createState() => _DwspPageState();
}
class _DwspPageState extends State<DwspGetList> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void dispose() {
_controller.dispose(); //销毁控制器
super.dispose();
}
@override
void initState() {
hyshlx = widget.hyshlx;
iPage = 0;
listDwspGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList(theHyshlx: hyshlx, bShowToast: false).then((value) async {
//mapHyshlx[hyshlx]['api'];
listDwspGetList2 = value;
//按照用户选择的_selectedValue、_descending对listDwspGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
listDwinfoGetList2 = listDwspGetList2;
// int len = listDwspGetList2.length;
// for (int i = 0; i < len; i++) {
// getDwspUrl(index: listDwspGetList2[i]['id']).then((value) {
// listDwspGetList2[i]['dwsp_ok'] = true;
// if (value == '' || value == null) {
// listDwspGetList2[i]['dwsp_ok'] = false;
// }
// setState(() {});
// });
// }
});
// ///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据,返回 list
// ///获取点位信息数据
// listDwinfoGetList2.clear();
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// });
//监听点位视频信息数据更新事件
eventBus.on<DwspUpdateEvent>().listen((event) async {
print(event.str);
try_setState();
});
super.initState();
}
//点位信息数据
//{
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆",
// "dwzt": "正常"
//},
// Widget getDropdownButton() {
// //DropdownMenuItem项目文本list
// List<String> itemList = [
// '主键ID',
// '点位IP',
// '点位名称',
// '点位编号',
// '点位信息',
// '点位坐标',
// '点位描述',
// '点位状态',
// ];
Widget _getMonitorImage(String _image, int indexRecord,
{double width = 140, double height = 140}) {
return Container(
margin: EdgeInsets.only(),
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(
_image,
fit: BoxFit.cover,
//color: listDwspGetList2[indexRecord]['dwsp_ok'] ? null : Theme.of(context).disabledColor
),
);
}
Widget _getListTile(BuildContext context, int indexRecord) {
List listCoordinate = listDwspGetList2[indexRecord]["dwzb"].trim().split('|');
return Column(
children: <Widget>[
Container(
decoration: getingIndex == indexRecord
? BoxDecoration(
border: Border.all(width: 3, color: Colors.red),
borderRadius: BorderRadius.all(Radius.circular(5.0)),
)
: null,
child: ListTile(
//leading: new Icon(Icons.phone),
contentPadding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 0),
title: Text(
"${listDwspGetList2[indexRecord]['dwbh'].toString()}. ${listDwspGetList2[indexRecord]['dwmc']}",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
// subtitle: Text(
// 'dwIP:${listDwspGetList2[indexRecord]['dwip']},${listDwspGetList2[indexRecord]['dwzt']}',
// style: TextStyle(fontSize: 10)),
trailing: Container(
width: 200,
child: Row(
children: [
_getMonitorImage('assets/images/monitor.png', indexRecord),
SizedBox(width: 20),
Container(
width: 120,
child: Text(
'${listDwspGetList2[indexRecord]['dwms']}' +
', 经纬度:${listCoordinate[0]}、${listCoordinate[1]}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 14),
),
)
],
),
),
enabled: true,
onTap: () async {
// int ret = await Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => DwspContent(
// title: '点位视频信息详情',
// index: indexRecord,
// hyshlx: widget.hyshlx,
// ),
// ),
// );
//{
// "ret": 200,
// "data": {
// "id": 13,
// "dwip": "172.16.3.13",
// "dwmc": "外江路",
// "dwbh": 13,
// "dwinfo": "外江路往高铁站方向",
// "dwzb": "104.623547|28.74798",
// "dwms": "外江路往高铁站方向,识别中坝大桥往高铁站排放黑烟车辆",
// "dwzt": "正常",
// "video12": null,
// "video13": null,
// "video14": null,
// "video15": null,
// "video16": "/rtp/gb_play_34020000001320013016_34020000001320013016/hls.m3u8",
// "play_urlhead": "http://125.64.218.67:9903"
// },
// "msg": ""
// }
//getDwspUrl(index: indexRecord, context: context);
getDwspUrlNew(indexRecord: indexRecord, context: context);
//@山不在高水不在深 我用PC播放这个地址也等了45秒才开始,
// http://125.64.218.67:9903/rtp/gb_play_34020000001320013016_34020000001320013016/hls.m3u8
// getDwspUrl(index: indexRecord + 1).then((url) {
// print('index = ${(indexRecord + 1).toString()}, url = $url');
// urlnew = url;
//
// //获取视频地址失败
// if (!isVideoUrl(urlnew)) {
// return;
// }
//
// var ret = Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => PlayerPro(
// url: urlnew,
// title:
// '点位视频\n${(indexRecord + 1)}、${listDwinfoGetList2[indexRecord]['dwmc']}',
// //initVideoSize: Size(704.0, 576.0), //16比13
// //initVideoSize: Size(16, 9),
// )));
// print('ret = $ret');
// });
},
),
),
Divider(height: 1.0),
],
);
}
ScrollController _controller = ScrollController(); //ListView控制器
bool isLoading = false; //正在处理下载数据、跳转到首项、跳转到尾项等操作
int firstIndex = 0; //ListView当前显示页面首项0基序号
int lastIndex = 0; //ListView当前显示页面末项0基序号
int itemOnPage = 8; //估计一屏显示的项目数量
Widget getIconButton({IconData iconData, var onPressed, double iconSize = 22}) {
return SizedBox(
height: iconSize,
width: iconSize + 10,
child: IconButton(
padding: EdgeInsets.all(0.0),
icon: Icon(iconData, size: iconSize),
onPressed: onPressed,
),
);
}
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
getingDwVideo = false;
Navigator.pop(context);
},
),
Expanded(
child: Text("${mapHyshlx[hyshlx]['text']}",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: (0 == listDwspGetList2.length)
? getMoreWidget(color: Colors.black38)
: ListView.custom(
//itemExtent: 75.0, //列表项高度
controller: _controller,
cacheExtent: 1.0, // 只有设置了1.0 才能够准确的标记 position 位置
childrenDelegate: MyChildrenDelegate(
_getListTile,
childCount: listDwspGetList2.length,
),
),
),
onWillPop: () {
// 屏蔽点击返回键的操作
getingDwVideo = false;
Navigator.pop(context);
},
);
}
//DropdownButton需要设置初始值的时候,初始值必须是显示列表里面的值,否则会导致弹出框异常。
// 比如说:你的DropdownButton的items属性使用的是list这个列表里面的值,那么你的初始值应该在list[index]里面取,要不就会报错。
//
// There should be exactly one item with [DropdownButton]'s value: 0.0.
// Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
// 'package:flutter/src/material/dropdown.dart':
// Failed assertion: line 834 pos 15: 'items == null || items.isEmpty || value == null ||
// items.where((DropdownMenuItem<T> item) {
// return item.value == value;
// }).length == 1'
String _selectedValue = '点位编号';
bool _descending = false; //默认升序排列
Widget _getImage(String _image) {
return Container(
margin: EdgeInsets.only(),
height: ScreenUtil().setWidth(38),
width: ScreenUtil().setWidth(38),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(_image,
fit: BoxFit.cover, color: isLoading ? Theme.of(context).disabledColor : null));
}
//按照用户选择的_selectedValue、_descending对listDwspGetList2进行排序,并延时更新
Future _listSort({bool bShowToast = false}) {
if (!isLoading && listDwspGetList2.length > 0) {
isLoading = true;
try_setState();
switch (_selectedValue) {
default:
if (_descending) {
//按_selectedValue排序,降序
listDwspGetList2.sort((a, b) =>
(b[mapWzxxDataText[_selectedValue]]).compareTo(a[mapWzxxDataText[_selectedValue]]));
} else {
//按_selectedValue排序,升序
listDwspGetList2.sort((a, b) =>
(a[mapWzxxDataText[_selectedValue]]).compareTo(b[mapWzxxDataText[_selectedValue]]));
}
break;
}
Future.delayed(const Duration(milliseconds: 1000), () {
if (bShowToast) {
Fluttertoast.showToast(
msg: '按“${_selectedValue}”${_descending ? '降序' : '升序'}排列完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
isLoading = false;
try_setState(); //避免如下异常报错
});
}
}
Widget getDropdownButtonItemText(String item) {
return Row(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment(0, 0.28),
child: item == _selectedValue
? _descending
? _getImage('assets/images/descending.png')
: _getImage('assets/images/ascending.png')
// ? Icon(Icons.arrow_downward_outlined, size: 20)
// : Icon(Icons.arrow_upward_outlined, size: 20)
: SizedBox(),
),
SizedBox(
width: 3,
),
Container(
//alignment: Alignment(0, -1),
child: Text(item,
style: isLoading
? TextStyle(color: Theme.of(context).disabledColor)
: (item == _selectedValue ? TextStyle(color: Colors.blue) : null)),
),
],
);
}
//点位信息数据
//{
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆",
// "dwzt": "正常"
//},
Widget getDropdownButton() {
//DropdownMenuItem项目文本list
List<String> itemList = [
'主键ID',
'点位IP',
'点位名称',
'点位编号',
'点位信息',
'点位坐标',
'点位描述',
'点位状态',
];
//添加按'推送状态'排序
if (hyshlx != 'dwxx') {
// itemList.removeLast();
// itemList.addAll(['推送状态', '主键ID']);
}
//获取DropdownMenuItem项目组件list
List<DropdownMenuItem<String>> _dropDownMenuItems =
itemList.map<DropdownMenuItem<String>>((String item) {
return DropdownMenuItem<String>(
value: item,
child: getDropdownButtonItemText(item),
);
}).toList();
return Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: Container(
alignment: Alignment(0.7, 0),
width: 125,
margin: EdgeInsets.only(bottom: 0),
padding: EdgeInsets.only(left: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(width: 0),
//边框圆角设置
borderRadius:
BorderRadius.vertical(top: Radius.elliptical(2, 2), bottom: Radius.elliptical(2, 2)),
),
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isDense: true,
value: _selectedValue,
items: _dropDownMenuItems,
onChanged: (String selectedValue) {
if (isLoading) {
return;
}
if (_selectedValue == selectedValue) {
_descending = !_descending;
} else {
_descending = true;
}
_selectedValue = selectedValue;
print('_selectedValue = $_selectedValue');
//按照用户选择的_selectedValue、_descending对listDwspGetList2进行排序,并延时更新
_listSort(bShowToast: true);
},
),
),
),
);
}
}
//https://blog.csdn.net/u014803467/article/details/103750018
//Flutter 使用SliverChildBuilderDelegate获取ListView的第一个和最后一个可见Item序号
// 秋名山交警X 2019-12-28 23:52:52
class _SaltedValueKey extends ValueKey<Key> {
const _SaltedValueKey(Key key)
: assert(key != null),
super(key);
}
class MyChildrenDelegate extends SliverChildBuilderDelegate {
MyChildrenDelegate(
Widget Function(BuildContext, int) builder, {
int childCount,
bool addAutomaticKeepAlive = true,
bool addRepaintBoundaries = true,
}) : super(builder,
childCount: childCount,
addAutomaticKeepAlives: addAutomaticKeepAlive,
addRepaintBoundaries: addRepaintBoundaries);
// Return a Widget for the given Exception
Widget _createErrorWidget(dynamic exception, StackTrace stackTrace) {
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stackTrace,
library: 'widgets library',
context: ErrorDescription('building'),
);
FlutterError.reportError(details);
return ErrorWidget.builder(details);
}
@override
Widget build(BuildContext context, int index) {
assert(builder != null);
if (index < 0 || (childCount != null && index >= childCount)) return null;
Widget child;
try {
child = builder(context, index);
} catch (exception, stackTrace) {
child = _createErrorWidget(exception, stackTrace);
}
if (child == null) return null;
final Key key = child.key != null ? _SaltedValueKey(child.key) : null;
if (addRepaintBoundaries) child = RepaintBoundary(child: child);
if (addSemanticIndexes) {
final int semanticIndex = semanticIndexCallback(child, index);
if (semanticIndex != null)
child = IndexedSemantics(index: semanticIndex + semanticIndexOffset, child: child);
}
if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child);
return KeyedSubtree(child: child, key: key);
}
@override
void didFinishLayout(int _firstIndex, int _lastIndex) {
// TODO: implement didFinishLayout
super.didFinishLayout(_firstIndex, _lastIndex);
}
///监听 在可见的列表中 显示的第一个位置和最后一个位置
@override
double estimateMaxScrollOffset(
int _firstIndex, int _lastIndex, double _leadingScrollOffset, double _trailingScrollOffset) {
//违章信息Listview滚动广播
eventBus.fire(WzxxDataScrollEvent(_firstIndex, _lastIndex));
return super.estimateMaxScrollOffset(
_firstIndex, _lastIndex, _leadingScrollOffset, _trailingScrollOffset);
}
}
+828
View File
@@ -0,0 +1,828 @@
//import '../../../widget/player_pro.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flustars/flustars.dart'
as flustars; //该组件中有ScreenUtil,// 获取网络图片尺寸flustars.WidgetUtil
import 'package:flutter/material.dart';
import 'package:flutter_drag_scale/flutter_drag_scale.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/widget/my_superplayer.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
//
import '../../../components/commonFun.dart';
//import 'package:hyzp_ybqx/widget/player_pro_new.dart';
import '../../../components/dioFun.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
class FhycxContentNew extends StatefulWidget {
FhycxContentNew({
@required this.hyshlx,
@required this.title,
this.indexRecord,
this.id,
Key key,
}) : super(key: key);
String title;
int indexRecord = 0;
int id = -1;
String hyshlx;
_FhycxPageState createState() => _FhycxPageState();
}
//用TabController实现顶部tab切换
class _FhycxPageState extends State<FhycxContentNew> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
dispose() {
super.dispose();
}
BuildContext _context;
String _title = '';
//flutter_screenUtil 4.x 用法,ScreenUtil.screenWidth (sdk>=2.6 : 1.sw) //设备宽度
double _screenWidth = 1.sw;
double _marginLeft = 25;
double _marginCenter = 20;
double _fontSize = 16;
double _widthLeft = 40; // = _screenWidth / 3;
double _iconSize = 18;
double _stampSize = 100;
double _listTileHeight = 30;
Color _iconColor = Colors.blue;
double _marginVer = 10;
Map _mapTsjjGetTsStatus = {};
void initState() {
super.initState();
_context = context;
_widthLeft = _screenWidth / 2.6;
getListFlields();
}
Map _mapGetTsjjGetData = {
"ret": 200,
"data": {
"id": 1203,
"plate_id": "川QS9661",
"plate_color": "蓝色",
"zpsj": 1612770967,
"yjxx_id": "1379",
"workflow": 2,
"video_url": "video/9_6063_20210208_155607_川QS9661.mp4",
"pic_url": "/wwwroot/admin/Api/wwwroot/public/uploads/926f5168f1fe109a9b8ec88dcac7ac2c.jpg",
"clfl": "皮卡车",
"dwip": "172.16.3.9",
"dwms": "宜长路出城方向",
"lgmzs": 3,
"jczxd": "863",
"sfhy": "黑烟车"
},
"msg": ""
};
double _radioImage = 9 / 16;
getListFlields() async {
_mapGetTsjjGetData = await getWzxxItemData(widget.id); //获取指定id的违章信息返回 _mapGetTsjjGetData
print('_mapGetTsjjGetData = ${_mapGetTsjjGetData}');
await getShenheData(widget.id); //获取指定id的审核信息存入 listGetShenheData
await getMapGetShenheData(); //从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
// 获取推送交警状态信息
// tsjjGetTsStatus返回字段 类型 说明
// id 整型 违章记录ID
// checkid 整型 推送的抓拍记录ID
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 3-推送成功
// ts_time 字符串 推送时间
//Future tsjjGetTsStatus(int _wzxxID)
_mapTsjjGetTsStatus = await tsjjGetTsStatus(widget.id);
// 获取网络图片尺寸
flustars.WidgetUtil.getImageWH(url: getMediaUrl(_mapGetTsjjGetData['pic_url'])).then((rect) {
if (null != rect) {
_radioImage = rect.height / rect.width;
}
});
imageWztp = getWztp(); //得到违章图片
//下面读取的是全局数据,该模块不需要修改
// 川Q565H4
try {
//_title = '${widget.title}(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})id:${listHycsGetList2[widget.indexRecord]['id']}';
//_title = '${widget.title}(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length}):${listHycsGetList2[widget.indexRecord]["plate_id"]}(${listHycsGetList2[widget.indexRecord]["plate_color"]})';
_title =
'${widget.title}(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})';
setState(() {});
} catch (e) {}
}
// 使用 cached_network_image 插件实现网络图片缓存
// 使用 flutter_drag_scale 实现可缩放可拖拽双击放大的图片功能。PhotoView插件不好用,有问题
Widget getNetworkImage(String url) {
return CachedNetworkImage(
imageUrl: url,
alignment: Alignment.topCenter,
imageBuilder: (context, imageProvider) => DragScaleContainer(
doubleTapStillScale: true, child: Image(image: imageProvider)
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
// imageBuilder: (context, imageProvider) => PhotoView(
// imageProvider: imageProvider,
// ),
//placeholder: (context, url) => CircularProgressIndicator(),
placeholder: (context, url) =>
getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
// 167 50 3.34
Widget getLgmzs(int lgmzs, {double width = 127, double height = 127}) {
int _rgb = (255 * (5 - lgmzs)) ~/ 5;
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 4),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('$lgmzs级${lgmzs * 20}%', style: TextStyle(fontSize: 10)),
//SizedBox(height: 0),
Container(
width: ScreenUtil().setWidth(66),
height: ScreenUtil().setHeight(66),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Color.fromRGBO(_rgb, _rgb, _rgb, 1.0),
borderRadius: new BorderRadius.circular(0),
),
)
],
),
),
Positioned(
top: ScreenUtil().setHeight(4),
child: Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height - 8),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: (lgmzs == _mapGetTsjjGetData['lgmzs'])
? Colors.red
: Color.fromRGBO(244, 244, 244, 1),
width: 2),
//color: Colors.lightBlue,
borderRadius: new BorderRadius.circular(3.0),
),
),
)
],
);
}
//得到tsjj页面组件
//1、得到格林曼黑度标准和视频播放按钮组件
Widget getHdAndPlay() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getLgmzs(0),
getLgmzs(1),
getLgmzs(2),
getLgmzs(3),
getLgmzs(4),
getLgmzs(5, width: 153),
getIconBtnSizeX(
height: 104,
//getIconBtnSizeX 中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 168,
text: "视频",
textSize: 12,
circular: 4,
color: Color.fromRGBO(52, 157, 237, 1),
onTop: () async {
if (Playing) {
//禁止同时启动两次播放器
return;
}
Playing = true; //禁止同时启动两次播放器
urlnew = getMediaUrl(_mapGetTsjjGetData['video_url']);
//获取视频地址失败
if (!isVideoUrl(urlnew)) {
return;
}
Navigator.of(_context).push(MaterialPageRoute(
builder: (context) => SuperPlayerPage(
loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
url: urlnew,
title:
'违章视频: ${_mapGetTsjjGetData["plate_id"]}\n${_mapGetTsjjGetData['dwms']}')));
// Navigator.of(_context).push(MaterialPageRoute(
// builder: (context) => PlayerProNew(
// loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
// url: urlnew,
// title:
// '违章视频: ${_mapGetTsjjGetData["plate_id"]}\n${_mapGetTsjjGetData['dwms']}')));
},
),
SizedBox(width: ScreenUtil().setWidth(15)),
],
);
}
Widget imageWztp;
//2、得到违章图片组件
Widget getWztp() {
//ratioList[index] = 0.5714285714285714
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(1022),
//height: ScreenUtil().setHeight(639),
//height: ScreenUtil().setHeight(22 + 1022 * _radioImage),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
decoration: BoxDecoration(
//color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
Positioned(
//left: ScreenUtil().setWidth(_marginLeft),
top: ScreenUtil().setHeight(_marginLeft),
child: Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
child: getNetworkImage(getMediaUrl(_mapGetTsjjGetData['pic_url'])),
),
)
],
);
}
// void printScreenInformation() {
// print('Device width dp:${1.sw}dp');
// print('Device height dp:${1.sh}dp');
// print('Device pixel density:${ScreenUtil().pixelRatio}');
// print('Bottom safe zone distance dp:${ScreenUtil().bottomBarHeight}dp');
// print('Status bar height dp:${ScreenUtil().statusBarHeight}dp');
// print('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}');
// print(
// 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}');
// print('System font scaling:${ScreenUtil().textScaleFactor}');
// print('0.5 times the screen width:${0.5.sw}dp');
// print('0.5 times the screen height:${0.5.sh}dp');
// }
void printScreenInformation() {
print('ScreenUtil().screenWidth = ${ScreenUtil().screenWidth}');
print('设备宽度:${1.sw}dp');
print('"1.w" = ${1.w}');
print('"1.sw" = ${1.sw}');
print('设备高度:${1.sh}dp');
print('设备的像素密度:${ScreenUtil().pixelRatio}');
print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');
print('状态栏高度:${ScreenUtil().statusBarHeight}dp');
print('实际宽度的dp与设计稿px的比例:${ScreenUtil().scaleWidth}');
print('实际高度的dp与设计稿px的比例:${ScreenUtil().scaleHeight}');
print('宽度和字体相对于设计稿放大的比例:${ScreenUtil().scaleWidth * ScreenUtil().pixelRatio}');
print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight * ScreenUtil().pixelRatio}');
print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');
print('屏幕宽度的0.5:${0.5.sw}dp');
print('屏幕高度的0.5:${0.5.sh}dp');
}
//3、得到违章图片说明信息组件
Widget getWztpSmxx() {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(280),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getWzxxPart1(),
getWzxxPart2(),
getWzxxPart3(),
],
),
);
}
// I/flutter (22989): ScreenUtil().screenWidth = 360.0
// I/flutter (22989): 设备宽度:360.0dp
// I/flutter (22989): "1.w" = 0.3333333333333333
// I/flutter (22989): "1.sw" = 360.0
// I/flutter (22989): 设备高度:640.0dp
// I/flutter (22989): 设备的像素密度:3.0
// I/flutter (22989): 底部安全区距离:0.0dp
// I/flutter (22989): 状态栏高度:24.0dp
// I/flutter (22989): 实际宽度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 实际高度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 宽度和字体相对于设计稿放大的比例:1.0
// I/flutter (22989): 高度相对于设计稿放大的比例:1.0
// I/flutter (22989): 系统的字体缩放比例:1.0
// I/flutter (22989): 屏幕宽度的0.5:180.0dp
// I/flutter (22989): 屏幕高度的0.5:320.0dp
//3、得到违章信息组件1:车牌号码、车牌颜色
//车牌颜色Map cpysMap = {
// '蓝色': cpysItem(
// cpysText: '蓝色',
// cpysBackground: Colors.blue,
// cpysFont: Colors.white,
// cpysBorder: Colors.orange),
// }
Widget getWzxxPart1() {
//printScreenInformation();
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
getTitleText('车牌号码:'),
getBoderText(_mapGetTsjjGetData['plate_id'].toString(),
width: ScreenUtil().setWidth(1022 / 3.2)),
SizedBox(width: ScreenUtil().setWidth(_marginCenter)),
getTitleText('颜色:'),
getBoderText(_mapGetTsjjGetData['plate_color'], width: ScreenUtil().setWidth(1022 / 4.8)),
],
);
}
Widget getTitleText(String text, {double fontSize = 16}) {
return Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis);
}
Widget getTrailText(String text, {double fontSize = 16, double off = 0}) {
return Container(
width: _screenWidth - _widthLeft - off - (2 * ScreenUtil().setWidth(_marginLeft)),
child: Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
);
}
Widget getBoderText(String text, {double width = 40}) {
cpysItem _cpysItem = cpysMap[_mapGetTsjjGetData['plate_color']];
return Container(
//color: _cpysItem.cpysBackground,
alignment: Alignment(0, -1),
width: width,
decoration: BoxDecoration(
border: Border.all(color: _cpysItem.cpysBorder, width: 2),
color: _cpysItem.cpysBackground,
borderRadius: BorderRadius.circular(3),
),
child: Padding(
padding: EdgeInsets.only(bottom: 3),
child: Text(text,
style: TextStyle(fontSize: _fontSize, color: _cpysItem.cpysFont),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
),
);
}
//I/flutter (17555): _mapGetTsjjGetData = {
// id: 1222, plate_id: 川Q736X2, plate_color: 蓝色, zpsj: 1612857077, yjxx_id: 1399, workflow: 999,
// video_url: video/9_6063_20210209_155117_川Q736X2.mp4,
// pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/9d2f45fd24b41f2b94abe42b30970d75.jpg,
// clfl: 集装箱卡车, dwip: 172.16.3.9, dwms: 宜长路出城方向, lgmzs: 3, jczxd: 994, sfhy: 黑烟车
// }
Widget getIcon(IconData _iconData) {
return Container(
width: _iconSize - 2,
height: _iconSize,
child: Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(_iconData, size: _iconSize, color: _iconColor),
),
);
}
//4、得到违章信息组件2:抓拍时间组件
Widget getWzxxPart2() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - ScreenUtil().setWidth(_marginLeft),
child: getTitleText(
'抓拍时间:' +
getDate(
(_mapGetTsjjGetData['zpsj'] is int)
? _mapGetTsjjGetData['zpsj']
: int.parse(_mapGetTsjjGetData['zpsj']),
),
),
),
],
);
}
Widget getWzxxPart3() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - ScreenUtil().setWidth(_marginLeft),
child: getTitleText('抓拍地点:' + _mapGetTsjjGetData['dwms']),
),
],
);
}
//6、得到审核信息组件4:违章类型、格林曼黑度组件
Widget getWzxxPart4() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: _widthLeft,
child: getTitleText('违章类型:' + _mapGetTsjjGetData['sfhy']),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
//getIcon(Icons.location_on_outlined),
Container(
width: _iconSize,
height: _iconSize,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(image: AssetImage("assets/images/hyc.png"), fit: BoxFit.contain),
),
alignment: Alignment.center,
//child:
),
getTrailText(':' + _mapGetTsjjGetData['lgmzs'].toString(), off: _iconSize),
],
);
}
//从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
//7、得到审核信息组件5:初审人员,初审时间
Widget getWzxxPart5() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: _widthLeft,
child: getTitleText('初审人员:' + mapGetHycsShenheData['uname']),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
getIcon(Icons.query_builder),
getTrailText(':' + mapGetHycsShenheData['addtime'], off: _iconSize),
],
);
}
//8、得到审核信息组件6:复审人员,复审时间
Widget getWzxxPart6() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: _widthLeft,
child: getTitleText('复审人员:' + mapGetHyfhShenheData['uname']),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
getIcon(Icons.query_builder),
getTrailText(':' + mapGetHyfhShenheData['addtime'], off: _iconSize),
],
);
}
//5、得到黑烟初审'hycsInfo'、或者黑烟'hyfhInfo'複核信息组件
//style: TextStyle(fontSize: _fontSize),
Widget getHyshInfo(String _hyshInfo) {
String _hyshlx = '初审';
Map _hyshMap = mapGetHycsShenheData;
if (_hyshInfo == 'hyfhInfo') {
_hyshlx = '复审';
if (mapGetHyfhShenheData.isNotEmpty) {
_hyshMap = mapGetHyfhShenheData;
} else {
//保留_hyshMap所有字段,但遍历清空所有字段的值
_hyshMap.forEach((var key, var value) {
_hyshMap[key] = '';
});
}
}
double _radio = 2.2;
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(161),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) / _radio,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text('$_hyshlx结果:' + _hyshMap['title'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
SizedBox(width: ScreenUtil().setWidth(6)),
Container(
width: my_iconSize,
height: my_iconSize,
decoration: _hyshMap['title'] == ''
? null
: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
image: AssetImage(_hyshMap['title'] == "黑烟车"
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
alignment: Alignment.center,
//child:
),
],
),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Expanded(
child: Text('意见:' + _hyshMap['shuoming'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) / _radio,
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text('$_hyshlx用户:' + _hyshMap['uname'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
]),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Expanded(
child: Text('时间:' + _hyshMap['addtime'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
),
],
),
],
),
);
}
//9、得到推送交警状态信息组件7:推送状态
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 3-推送成功
//_mapTsjjGetTsStatus['tszt']
Widget getWzxxPart7() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: _screenWidth - ScreenUtil().setWidth(_marginLeft),
child: getTitleText('推送状态:' + mapTsztText[_mapTsjjGetTsStatus['tszt']]),
),
],
);
}
//10、得到推送交警确认组件
Widget getTsjjQr() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(
text: "返回",
onPressedFun: () async {
Navigator.pop(context);
},
width: 90.0),
],
);
}
bool showMoreWidget = false;
@override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: showMoreWidget
? null
: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(_title,
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 30),
],
),
),
),
),
body: null == imageWztp
// 显示加载中的圈圈
? getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0)
: Stack(
children: [
//SizedBox.shrink() 创建父类允许最小尺寸的约束Box
showMoreWidget
? Align(
alignment: Alignment(0, 0.8),
child: Container(
height: 200,
width: 200,
child: getMoreWidget2(
text: '推送中...',
color: Colors.red,
size: 40.0,
strokeWidth: 3.0), //显示加载中的圈圈,
),
)
: SizedBox.shrink(),
KeyboardAvoider(
autoScroll: true,
child: Container(
color: Color.fromRGBO(244, 244, 244, 1),
child: Column(
children: <Widget>[
//1、得到格林曼黑度标准和视频播放按钮组件
getHdAndPlay(),
//2、得到违章图片组件
imageWztp,
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//3、得到违章图片说明信息组件
getWztpSmxx(),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//7、得到黑烟初审信息组件
getHyshInfo('hycsInfo'),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//8、得到黑烟复审信息组件
getHyshInfo('hyfhInfo'),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
// //7、得到审核信息组件5:初审人员,初审时间
// getWzxxPart5(),
// //8、得到审核信息组件6:复审人员,复审时间
// getWzxxPart6(),
// SizedBox(height: 6),
// Divider(height: 1.0, color: Colors.blue),
// SizedBox(height: 6),
//6、得到推送交警状态信息组件7:推送状态
//getWzxxPart7(),
// SizedBox(height: 8),
// Divider(height: 1.0, color: Colors.blue),
SizedBox(height: 18),
//9、得到推送交警确认组件
getTsjjQr(),
SizedBox(height: 10),
],
),
),
),
Positioned(
//alignment: Alignment(0.9, 0.35),
//alignment: Alignment(0.8, 0.45),
right: ScreenUtil().setWidth(80),
top: ScreenUtil().setHeight(1045),
child: Container(
//alignment: Alignment(0.5, -0.5),
width: _stampSize,
height: _stampSize,
//color: Colors.black12,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
//image: AssetImage("assets/images/jkzx_stamp.png"), fit: BoxFit.contain),
image: AssetImage("assets/images/fhyc.png"),
fit: BoxFit.contain),
),
//child:
),
),
],
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
+919
View File
@@ -0,0 +1,919 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/widget/JdButton.dart';
//import 'package:hyzp_ybqx/widget/player_pro_new.dart';
import '../../../widget/CarNumberAndCpysItems.dart';
import '../../../components/dioFun.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../services/EventBus.dart';
import '../../../components/commonFun.dart';
import '../../../config/service_url.dart';
//import '../../../widget/player_pro.dart';
import '../../../widget/customRadioWidget.dart';
import 'package:dio/dio.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:photo_view/photo_view.dart';
//屏幕适配 flutter_screenutil 库与 flustars(获取网络图片尺寸要用到其 WidgetUtil) 库使用的 ScreenUtil() 类名冲突
// 解决办法是将 flustars 库取个别名 as flustars
import 'package:flustars/flustars.dart' as flustars;
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
import 'package:flutter_drag_scale/flutter_drag_scale.dart';
import 'hysh_group.dart';
import 'package:hyzp_ybqx/widget/my_superplayer.dart';
class HyshContentNew extends StatefulWidget {
HyshContentNew({
@required this.hyshlx,
@required this.title,
this.indexRecord,
this.id,
Key key,
}) : super(key: key);
String title;
int indexRecord = 0;
int id = -1;
String hyshlx;
_HyshPageState createState() => _HyshPageState();
}
//用TabController实现顶部tab切换
class _HyshPageState extends State<HyshContentNew> with SingleTickerProviderStateMixin {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
//获取黑烟初审单条数据
//接口地址:http://49.235.208.235:9001/?s=App.Car_Yjxx.Get
//接口参数
// 参数名字 类型 是否必须 默认值 其他 说明
// id 字符串 必须 最小:1 ID
//List<TextEditingController> listController = [];
//List<List<TextEditingController>> listZpljController = [];
List ratioList = [];
//用TabController实现顶部tab切换
TabController _tabController;
//监听登录页面销毁的事件
dispose() {
_tabController?.dispose();
super.dispose();
//eventBus.fire(UserEvent('登录成功...'));
}
//int listLen = 0;
String nums = '';
bool bModifiable = false;
String cpysText = '';
String myCpys = '蓝色';
void initState() {
// TODO: implement initState
fh_hyc = true;
tsjj = true;
_context = context;
getListFlields();
// //监听违章信息数据更新事件
// eventBus.on<HycsDataUpdateEvent>().listen((event) {
// print(event.str);
// getListFlields();
// });
// //监听违章信息数据审核事件
// eventBus.on<WzxxDataAuditEvent>().listen((event) {
// print('HycsContentModify: ' + event.str);
// getListFlields();
// });
//黑监听烟初审数据审核Radio选项改变事件
eventBus.on<HycsDataAuditRadioEvent>().listen((event) {
print(event.str);
print('event.selectedRadio = ${event.selectedRadio.toString()}');
if (null != _tabController) {
topTabs_map['auditTitle'][_tabController.index] =
(event.selectedRadio == 0) ? hyc_text : fhyc_text;
topTabs_map['auditShuoming_Controller_List'][_tabController.index].text =
((widget.hyshlx == 'hyfh') ? '初审为' + mapGetHycsShenheData['title'] + '。复审' : '') +
((event.selectedRadio == 0) ? hyc_shyj : fhyc_shyj);
//解决 setState(() {}); 抛异常Unhandled Exception: setState() called after dispose():
try_setState(); //避免如下异常报错
}
});
//黑烟审核推送交警Checkbox改变事件
eventBus.on<HycsDataAuditCheckboxButton>().listen((event) {
print(event.str);
if (null != _tabController) {
//解决 setState(() {}); 抛异常Unhandled Exception: setState() called after dispose():
try_setState(); //避免如下异常报错
}
});
//黑烟初审数据审核Dropdown选项改变事件
eventBus.on<HycsDataAuditDropdownEvent>().listen((event) {
print(event.str);
print('event.selectedValue = ${event.selectedValue}');
print('_tabController.index = ${_tabController.index}');
//topTabs_map['cpysText_List'][_tabController.index] = event.selectedValue; //这样报错如下
myCpys = event.selectedValue;
try_setState(); //避免如下异常报错
//This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer inc
// ludes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
// topTabs_map['carNumberAndCpys_List'][_tabController.index] =
// getCarNumberAndCpys(_tabController.index);
//延时500毫秒执行
// Future.delayed(const Duration(milliseconds: 10), () {
// print('延时后输出:_tabController.index = ${_tabController.index}');
// //延时执行的代码
// //延时更新状态
// setState(() {});
// });
});
super.initState();
}
//避免如下异常报错
// try {
// setState(() {});
// } catch (e) {}
//E/flutter (12227): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: setState() called after dispose(): _LoginPageState#c4f60(lifecycle state: defunct, not mo
// unted, ticker inactive)
// E/flutter (12227): This error happens if you call setState() on a State object for a widget that no longer appears in the widget tree (e.g., whose parent widget no longer inc
// ludes the widget in its build). This error can occur when code calls setState() from a timer or an animation callback.
// E/flutter (12227): The preferred solution is to cancel the timer or stop listening to the animation in the dispose() callback. Another solution is to check the "mounted" prop
// erty of this object before calling setState() to ensure the object is still in the tree.
// E/flutter (12227): This error might indicate a memory leak if setState() is being called because another object is retaining a reference to this State object after it has bee
// n removed from the tree. To avoid memory leaks, consider breaking the reference to this object during dispose().
// E/flutter (12227): #0 State.setState.<anonymous closure> (package:flutter/src/widgets/framework.dart:1208:9)
// E/flutter (12227): #1 State.setState (package:flutter/src/widgets/framework.dart:1243:6)
// E/flutter (12227): #2 _LoginPageState.getZpjlFields (package:hyzp_ybqx/pages/Works/HYSH/hysh_content.dart:163:7)
// E/flutter (12227): #3 _rootRunUnary (dart:async/zone.dart:1198:47)
// E/flutter (12227): #4 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
// E/flutter (12227): #5 _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
// E/flutter (12227): #6 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
// E/flutter (12227): #7 Future._propagateToListeners (dart:async/future_impl.dart:725:32)
// E/flutter (12227): #8 Future._completeWithValue (dart:async/future_impl.dart:529:5)
// E/flutter (12227): #9 Future._asyncCompleteWithValue.<anonymous closure> (dart:async/future_impl.dart:567:7)
// E/flutter (12227): #10 _rootRun (dart:async/zone.dart:1190:13)
// E/flutter (12227): #11 _CustomZone.run (dart:async/zone.dart:1093:19)
// E/flutter (12227): #12 _CustomZone.runGuarded (dart:async/zone.dart:997:7)
// E/flutter (12227): #13 _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
// E/flutter (12227): #14 _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
// E/flutter (12227): #15 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)
// E/flutter (12227):
// E/flutter (12227): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: 'package:flutter/src/widgets/media_query.dart': Failed assertion: line 812 pos 12: 'conte
// xt != null': is not true.
// E/flutter (12227): #0 _AssertionError._doThrowNew (dart:core-patch/errors_patch.dart:46:39)
// E/flutter (12227): #1 _AssertionError._throwNew (dart:core-patch/errors_patch.dart:36:5)
// E/flutter (12227): #2 MediaQuery.of (package:flutter/src/widgets/media_query.dart:812:12)
// E/flutter (12227): #3 _LoginPageState.getTopTabsMap (package:hyzp_ybqx/pages/Works/HYSH/hysh_content.dart:415:41)
// E/flutter (12227): #4 _LoginPageState.getZpjlFields (package:hyzp_ybqx/pages/Works/HYSH/hysh_content.dart:162:7)
//getListFlields({bool b = true}) async {
getListFlields() async {
//await getHycsGetData();
//Unhandled Exception: type 'List<dynamic>' is not a subtype of type 'Map<dynamic, dynamic>'
//print('getListFlields().mapGetHycsGetData = ${mapGetHycsGetData}');
//if (b) {
//listZpljController.clear();
listGetZpjl.clear(); //必须先行清空,否则会出现记录数据错位问题
listFieldModify.clear();
mapGetHycsGetData.clear();
//1、获取指定id的抓拍记录列表存入listGetZpjl
//2、如果是黑烟复审,还需获取指定id的违章记录审核信息存入mapGetShenheData
await getItemData(widget.id);
//}
print('getListFlields().listGetZpjl = ${listGetZpjl}');
//print('getListFlields().mapGetHycsGetData = ${mapGetHycsGetData}');
await getZpjlFields();
//nums = '${(widget.indexRecord + 1).toString()} / $listLen';
try {
// nums = '(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})id:${listHycsGetList2[widget.indexRecord]['id']}';
nums = '(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})';
setState(() {});
} catch (e) {}
//setState(() {}); //刚进入时,执行该语句会会抛异常
//print('mapGetHycsGetData = \n${mapGetHycsGetData}');
}
Future getZpjlFields() async {
if (listGetZpjl.isNotEmpty) {
int len = listGetZpjl.length;
for (int i = 0; i < len; i++) {
// 获取网络图片尺寸
Rect rect =
await flustars.WidgetUtil.getImageWH(url: getMediaUrl(listGetZpjl[i]['pic_url']));
ratioList.add(rect.height / rect.width);
print("rect: " + rect.toString());
print("ratio: " + ratioList[i].toString());
}
await getTopTabsMap();
//用TabController实现顶部tab切换
_tabController = TabController(vsync: this, length: topTabs_map['listView_List'].length);
_tabController.addListener(() {
print('_tabController.index = ${_tabController.index}');
//Tab切换时,设置 sfyc 和 tsjj,只处理当前选中的抓拍记录 _tabController.index
set_sfyc_tsjj(int.parse(listGetZpjl[_tabController.index]['zpsj']));
//Tab切换时,初始化所有审核意见
int len = listGetZpjl.length;
for (int i = 0; i < len; i++) {
topTabs_map['auditShuoming_Controller_List'][i].text =
((widget.hyshlx == 'hyfh') ? '初审为' + mapGetHycsShenheData['title'] + '。复审' : '') +
hyc_shyj;
}
});
print('first : _tabController.index = ${_tabController.index}');
set_sfyc_tsjj(int.parse(listGetZpjl[_tabController.index]['zpsj']));
//避免如下异常报错
try_setState(); //避免如下异常报错
}
}
// 使用 cached_network_image 插件实现网络图片缓存
// 使用 flutter_drag_scale 实现可缩放可拖拽双击放大的图片功能。PhotoView插件不好用,有问题
Widget getNetworkImage(String url) {
return CachedNetworkImage(
imageUrl: url,
alignment: Alignment.topCenter,
imageBuilder: (context, imageProvider) => DragScaleContainer(
doubleTapStillScale: true, child: Image(image: imageProvider)
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
// imageBuilder: (context, imageProvider) => PhotoView(
// imageProvider: imageProvider,
// ),
//placeholder: (context, url) => CircularProgressIndicator(),
placeholder: (context, url) =>
getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
//使用 cached_network_image 插件实现网络图片缓存
Widget getNetworkImage1(String url) {
return CachedNetworkImage(
imageUrl: url,
alignment: Alignment.topCenter,
//placeholder: (context, url) => CircularProgressIndicator(),
imageBuilder: (context, imageProvider) => PhotoView(
imageProvider: imageProvider,
),
placeholder: (context, url) =>
getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
//3、得到违章图片说明信息组件
Widget getWztpSmxx(int index) {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(141),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getWztpSmxx1(index),
getWztpSmxx2(index),
],
),
);
}
//3.1、得到违章图片说明信息1:黑度、抓拍时间组件
Widget getWztpSmxx1(int index) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: ScreenUtil().setWidth(_marginLeft)),
width: ScreenUtil().setWidth(_preItem),
child:
Text('黑度:' + listGetZpjl[index]['lgmzs'].toString(), overflow: TextOverflow.ellipsis),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Icon(
Icons.query_builder,
size: ScreenUtil().setWidth(_iconSize),
color: _iconColor,
),
Container(
alignment: Alignment.centerLeft,
width: ScreenUtil().setWidth(1022 - _preItem - _marginLeft - _iconSize),
child: Text(
' :' +
getDate((listGetZpjl[index]['zpsj'] is int)
? listGetZpjl[index]['zpsj']
: int.parse(listGetZpjl[index]['zpsj'])),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
),
],
);
}
//3.2、得到违章图片说明信息:车型、抓拍地点组件
Widget getWztpSmxx2(int index) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: ScreenUtil().setWidth(_marginLeft)),
width: ScreenUtil().setWidth(_preItem),
child: Text('车型:' + listGetZpjl[index]['clfl'], overflow: TextOverflow.ellipsis),
),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Icon(
Icons.location_on_outlined,
size: ScreenUtil().setWidth(_iconSize),
color: _iconColor,
),
Container(
alignment: Alignment.centerLeft,
width: ScreenUtil().setWidth(1022 - _preItem - _marginLeft - _iconSize),
child: Text(' :' + listGetZpjl[index]['dwms'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis)),
],
);
}
//4、得到黑烟初审结果组件,在复审页面需要
Widget getHycsResult(int index) {
double _radio = 2.2;
return Column(
children: [
Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(141),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022 / _radio),
//height: ScreenUtil().setHeight(my_listTileHeight2),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text('初审结果: ' + mapGetHycsShenheData['title'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
SizedBox(width: ScreenUtil().setWidth(6)),
Container(
width: ScreenUtil().setWidth(_iconSize),
height: ScreenUtil().setHeight(_iconSize),
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
image: AssetImage(mapGetHycsShenheData['title'] == "黑烟车"
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
alignment: Alignment.center,
//child:
),
],
),
),
SizedBox(width: ScreenUtil().setWidth(10)),
Expanded(
child: Text('意见: ' + mapGetHycsShenheData['shuoming'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022 / _radio),
child: Row(mainAxisAlignment: MainAxisAlignment.start, children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text('初审用户: ' + mapGetHycsShenheData['uname'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
]),
),
SizedBox(width: ScreenUtil().setWidth(10)),
Expanded(
child: Text('时间: ' + mapGetHycsShenheData['addtime'],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
),
],
),
],
),
),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
],
);
}
// 167 50 3.34
Widget getLgmzs(int index, int lgmzs, {double width = 127, double height = 127}) {
int _rgb = (255 * (5 - lgmzs)) ~/ 5;
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 4),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('$lgmzs级${lgmzs * 20}%', style: TextStyle(fontSize: 10)),
//SizedBox(height: 0),
Container(
width: ScreenUtil().setWidth(66),
height: ScreenUtil().setHeight(66),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Color.fromRGBO(_rgb, _rgb, _rgb, 1.0),
borderRadius: new BorderRadius.circular(0),
),
)
],
),
),
Positioned(
top: ScreenUtil().setHeight(4),
child: Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height - 8),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: (lgmzs == listGetZpjl[index]['lgmzs'])
? Colors.red
: Color.fromRGBO(244, 244, 244, 1),
width: 2),
//color: Colors.lightBlue,
borderRadius: new BorderRadius.circular(3.0),
),
),
)
],
);
}
//1、得到格林曼黑度标准和视频播放按钮组件
Widget getHdAndPlay(int index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getLgmzs(index, 0),
getLgmzs(index, 1),
getLgmzs(index, 2),
getLgmzs(index, 3),
getLgmzs(index, 4),
getLgmzs(index, 5, width: 153),
getIconBtnSizeX(
height: 104,
//getIconBtnSizeX 中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 168,
text: "视频",
textSize: 12,
circular: 4,
color: Color.fromRGBO(52, 157, 237, 1),
onTop: () async {
if (Playing) {
//禁止同时启动两次播放器
return;
}
Playing = true; //禁止同时启动两次播放器
urlnew = getMediaUrl(listGetZpjl[index]['video_url']);
//获取视频地址失败
if (!isVideoUrl(urlnew)) {
return;
}
Navigator.of(_context).push(MaterialPageRoute(
builder: (context) => SuperPlayerPage(
loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
url: urlnew,
title:
'违章视频: ${listGetZpjl[index]["car_number"]}(抓拍${index + 1})\n${listGetZpjl[index]['dwms']}')));
// Navigator.of(_context).push(MaterialPageRoute(
// builder: (context) => PlayerProNew(
// loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
// url: urlnew,
// title:
// '违章视频: ${listGetZpjl[index]["car_number"]}(抓拍${index + 1})\n${listGetZpjl[index]['dwms']}')));
},
),
SizedBox(width: ScreenUtil().setWidth(15)),
],
);
}
//2、得到违章图片组件
Widget getWztp(int index) {
print('ratioList[index] = ${ratioList[index]}');
//ratioList[index] = 0.5714285714285714
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(1022),
//height: ScreenUtil().setHeight(639),
height: ScreenUtil()
.setHeight(22 + 1022 * (ratioList.isNotEmpty ? ratioList[index] : 9 / 16)),
decoration: BoxDecoration(
//color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
Positioned(
//left: ScreenUtil().setWidth(25),
top: ScreenUtil().setHeight(11),
child: Container(
width: ScreenUtil().setWidth(1022),
height:
ScreenUtil().setHeight(1022 * (ratioList.isNotEmpty ? ratioList[index] : 9 / 16)),
child: getNetworkImage(getMediaUrl(listGetZpjl[index]['pic_url'])),
),
)
],
);
}
double _fontSize = 16;
double _listTileHeight = 30;
double _iconSize = 55;
Color _iconColor = Colors.blue;
double _textFieldHeight = 8;
double _preItem = 360;
double _marginLeft = 33;
double _marginVer = 6;
BuildContext _context;
double _marginVertical1 = 3;
double _marginVertical2 = 5;
//double _marginVertical3 = 6;
double _marginVertical3 = 3;
//double _marginVertical4 = 10;
double _marginVertical4 = 6;
double _marginVertical5 = 10;
double _marginVertical6 = 20;
Future getTopTabsMap() async {
//map遍历,清空数据
topTabs_map.forEach((key, value) {
topTabs_map[key].clear();
});
int len = listGetZpjl.length;
for (int index = 0; index < len; index++) {
//顶部Tab标题
//topTabs_map['tabs_list'].add(Tab(text: '抓拍ID:${listGetZpjl[index]['id']}'));
topTabs_map['tabs_list'].add(Tab(text: '抓拍 ${(index + 1).toString()}'));
//可供用户修改的车牌号码
topTabs_map['car_number_List'].add(listGetZpjl[index]['car_number']);
//可供用户修改的车牌颜色
topTabs_map['cpysText_List'].add(listGetZpjl[index]['cpys']);
//可供用户修改的审核意见
topTabs_map['auditShuoming_Controller_List'].add(
TextEditingController.fromValue(TextEditingValue(
text: ((widget.hyshlx == 'hyfh') ? '初审为' + mapGetHycsShenheData['title'] + '。复审' : '') +
hyc_shyj,
// 保持光标在最后
selection: TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: hyc_shyj.length)))),
);
//可供用户修改的审核结果
topTabs_map['auditTitle'].add(hyc_text);
//车牌号码、车牌颜色
topTabs_map['carNumberAndCpys_List']
.add(CarNumberAndCpysItems(index, topTabs_map['cpysText_List'][index]));
//Tab页面
topTabs_map['listView_List'].add(
//flutter开发弹起键盘出现Overflow问题的解决方法,我出现的情况,这三种方法就可以解决。
KeyboardAvoider(
autoScroll: true,
child: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(244, 244, 244, 1),
),
child: Column(
children: <Widget>[
//1、得到格林曼黑度标准和视频播放按钮组件
getHdAndPlay(index),
//2、得到违章图片组件
getWztp(index),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//3、得到违章图片说明信息组件
getWztpSmxx(index),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//4、得到黑烟初审结果组件,在复审页面需要
widget.hyshlx == 'hyfh' ? getHycsResult(index) : SizedBox.shrink(),
//为了用户在切换审核结果Radio时显示不同图片,必须将以下组件都移入到RadioListItems类中
//5-6、得到黑烟审核组件、审核确认组件
HyshGroup(
index: index,
hyshlx: hyshlx,
fontSize: _fontSize,
size: Size(_listTileHeight, _listTileHeight),
id: widget.id),
//为了用户在切换审核结果Radio时显示不同图片,必须将以下组件都移入到RadioListItems类中
// SizedBox(height: 6),
// Divider(height: 1.0, color: Colors.blue),
// SizedBox(height: 10),
// //9、得到审核确认组件
// getShqr(index),
],
),
),
),
);
}
}
//flutter开发弹起键盘出现Overflow问题的解决方法
// 方法1:
// //Scaffold节点下添加resizeToAvoidBottomPadding: false,这样页面就不会随着键盘弹起而滚动。
// Scaffold(
// resizeToAvoidBottomPadding: false,
// body: Column()
// );
// 方法2:
// //外层使用SingleChildScrollView包裹一层,这样页面回随着键盘弹起而向上滚动。
// SingleChildScrollView(
// child: Column(
// children: [
// TextField()
// ],
// ),
// ),
// 方法3:
// //使用第三方库:keyboard_avoider,并且设置autoScroll为true
// pubspec.yaml文件下添加依赖:
// dependencies:
// keyboard_avoider: ^0.1.2
// 外层使用KeyboardAvoider包裹,设置autoScroll为true
// KeyboardAvoider(
// autoScroll: true
// child: Column(
// children: [
// TextField()
// ],
// )
// ),
// 我出现的情况,这三种方法就可以解决。
@override
Widget build(BuildContext context) {
print('topTabs_map[\'tabs_list\'].length = ${topTabs_map['tabs_list'].length}');
print('topTabs_map[\'listViewList\'].length = ${topTabs_map['listView_List'].length}');
return DefaultTabController(
//length: 8, //必须使用常数
//length: topTabs_map['tabs_list'].length,
length: topTabs_map['listView_List'].length,
//报错:Another exception was thrown: A RenderFlex overflowed by 99896 pixels on the bottom
//length: g_tabs, //报错: Another exception was thrown: RangeError (index): Invalid value: Valid value range is empty: 0
child: Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
child: AppBar(
//backgroundColor: Colors.black12,
// title: Text("${mapHyshlx[hyshlx]['text']}详情$nums",
// style: TextStyle(
// fontSize: _fontSize, color: myCpys == '绿色' ? Colors.green : Colors.blue)),
// title: Text("${mapHyshlx[hyshlx]['text']}详情$nums",
// style: TextStyle(fontSize: _fontSize)),
automaticallyImplyLeading: false,
centerTitle: true,
//leading: Text(''),
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
//1.1、返回按钮
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
// child: Text("${mapHyshlx[hyshlx]['text']}",
// textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
child: Text("${mapHyshlx[hyshlx]['text']}详情$nums",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 30),
],
),
),
),
),
body: Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(99)), // 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
//leading: Text(''),
titleSpacing: 0.0,
//设置title的左边距
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
),
//bottom必须要套PreferredSize,否则会报错:The argument type 'Container' can't be assigned to the parameter type 'PreferredSizeWidget'.
bottom: PreferredSize(
preferredSize: Size.fromHeight(30.0), // 设置TabBar高度
child: Container(
//color: Colors.blueAccent,
alignment: Alignment.centerLeft, //左对齐,有效
height: 30, // 设置TabBar高度
child: listGetZpjl.isNotEmpty
? TabBar(
//labelColor: Colors.blueAccent,
controller: _tabController,
//注意:用TabController实现顶部tab切换,必须添加该行
isScrollable: true,
//如果多个按钮的话可以自动左右移动
tabs: (topTabs_map['listView_List'].isNotEmpty)
? topTabs_map['tabs_list']
: [],
)
: PreferredSize(
preferredSize: Size.fromHeight(48.0),
child: Theme(
data: Theme.of(context).copyWith(accentColor: Colors.white),
child: Container(),
),
),
),
),
),
),
//: Container(),
//type 'Container' is not a subtype of type 'PreferredSizeWidget'
body: listGetZpjl.isNotEmpty
? TabBarView(
controller: _tabController, //注意:用TabController实现顶部tab切换,必须添加该行
physics: NeverScrollableScrollPhysics(), //必须放到TabBarView下面,禁止TabBarView左右滑动-OK
children:
(topTabs_map['listView_List'].isNotEmpty) ? topTabs_map['listView_List'] : [],
)
: getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0), //显示加载中的圈圈
),
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
// App.Car_Yjxx.Workflow
// 审核数据
// 接口地址:http://49.235.208.235:9001/?s=App.Car_Yjxx.Workflow
// 接口文档
// 根据ID审核数据库中的一条纪录数据
//
// 接口参数
// 参数名字 类型 是否必须 默认值 其他 说明
// id 整型 必须 最小:1 ID
// workflow 整型 必须 2 最小:1 审核标记: 2=>初审通过 | 999=>复审通过 | 1000=>确认为非黑烟车
// shuoming 字符串 必须 最小:1 审核意见:如 黑烟超标,交由交警处罚
// uid 字符串 必须 最小:1 审核用户ID
// 返回结果
// 返回字段 类型 说明
// code 整型 更新的结果,1表示成功,0表示无更新,false表示失败
//违章信息审核
Future<bool> auditWzxxData() async {
var api = ServicePath.auditWzxxUrl;
print(api);
try {
print('开始处理网络请求...');
Response response;
Dio dio = Dio();
await copyMapUpdateWzxxData(mapGetHycsGetData);
response = await dio.post(api, data: mapUpdateWzxxData);
print('response = ${response.toString()}');
if (response.statusCode == 200) {
print('违章信息更新网络请求过程正常完成');
return true;
} else {
throw Exception('后端接口出现异常,请检测代码和服务器情况.........');
}
} catch (e) {
print('网络请求过程异常e:${e}');
Fluttertoast.showToast(
msg: 'ERROR:======>${e}',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
return false;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+538
View File
@@ -0,0 +1,538 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/EncryptUtil.dart';
import 'package:hyzp_ybqx/components/customDialogF.dart';
import 'package:hyzp_ybqx/components/customDialogHysh.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../services/EventBus.dart';
import '../../../widget/CheckboxButtonItem.dart';
class HyshGroup extends StatefulWidget {
HyshGroup(
{@required this.index,
@required this.hyshlx,
this.size = const Size(30, 30),
this.fontSize = 16,
this.selectedRadio = 0,
this.id = -1});
//I don't know what is this index for but I will put it in anyway
final int index;
Size size;
double fontSize;
String hyshlx;
int selectedRadio;
int id;
@override
_HyshGroupState createState() => _HyshGroupState();
}
class _HyshGroupState extends State<HyshGroup> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
int _selectedRadio = 0;
String _sfcyTextTrue = '当前时间 > 抓拍时间 + 审核间隔,只能审核,不推送交警';
String _sfcyTextFalse = '当前时间 < 抓拍时间 + 审核间隔,复审后可以推送交警';
void initState() {
_selectedRadio = widget.selectedRadio;
//黑烟审核推送交警Checkbox改变事件
eventBus.on<HycsDataAuditSfyc>().listen((event) {
print(event.str);
try_setState(); //避免如下异常报错
});
super.initState();
}
Widget getRadio(int index, Size size) {
return Container(
alignment: Alignment(-1, 1),
width: size.width,
height: size.height,
child: Radio(
value: index,
onChanged: (value) {
_selectedRadio = value;
//黑烟初审数据审核Radio选项改变广播
eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
setState(() {});
print('selectedRadio = ${_selectedRadio.toString()}');
},
groupValue: _selectedRadio,
),
);
}
//Couldn't infer type parameter 'T'. Tried to infer 'dynamic' for 'T' which doesn't work:
// Parameter 'onChanged' declared as 'void Function(T)' but argument is 'Null Function(String)'.
// The type 'dynamic' was inferred from: Parameter 'value' declared as 'T' but argument is 'String'.
// Parameter 'groupValue' declared as 'T' but argument is 'dynamic'.
// Consider passing explicit type argument(s) to the generic.
//原因是selectedRadio的类型为int,示例中_radValue为String
//无法推断类型参数“t”。试图推断“T”的“dynamic”无效:参数“onChanged”声明为“void Function(T)”,
// 但参数为“Null Function(String)”。类型“dynamic”的推断依据:参数“value”声明为“T”,
// 但参数为“String”。参数“groupValue”声明为“T”,但参数为“dynamic”。考虑将显式类型参数传递给泛型。
//5、得到黑烟审核组件
getHyshItems(int index) {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(550),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(height: ScreenUtil().setHeight(20)),
//5.1、车牌号码、车牌颜色
topTabs_map['carNumberAndCpys_List'][index],
SizedBox(height: ScreenUtil().setHeight(15)),
//5.2、审核意见
getShyj(widget.index),
//SizedBox(height: ScreenUtil().setHeight(25)),
//5.3、得到审核结果组件
getShjg(widget.index),
],
),
);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
//5、得到黑烟审核组件
getHyshItems(widget.index),
SizedBox(height: ScreenUtil().setHeight(6)),
//6、得到审核确认组件
getShqr(widget.index),
],
);
}
//6、得到审核确认组件
Widget getShqr(int index) {
return Container(
//padding: EdgeInsets.only(top: ScreenUtil().setWidth(6)),
width: ScreenUtil().setWidth(1022),
height: ScreenUtil()
.setHeight(widget.hyshlx == 'hyfh' ? (1 == sfyc ? 215 : 150) : (1 == sfyc ? 215 : 150)),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
children: [
SizedBox(height: ScreenUtil().setHeight(20)),
1 == sfyc
? Container(
alignment: Alignment.centerLeft,
padding: EdgeInsets.only(left: ScreenUtil().setWidth(30)),
child: Text(
_sfcyTextTrue,
textAlign: TextAlign.left,
style: TextStyle(color: Colors.blue, fontSize: 13),
))
: SizedBox.shrink(),
SizedBox(height: ScreenUtil().setHeight(1 == sfyc ? 6 : 0)),
widget.hyshlx == 'hyfh'
? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
CheckboxButtonItem(widget.index),
//_getShjgImage(widget.tabController, _selectedRadio, 35),
Container(
width: ScreenUtil().setWidth(100),
height: ScreenUtil().setHeight(100),
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(_selectedRadio == 0
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
),
getBtnSizeX(
text: '复审提交',
fontColor: 0 == _selectedRadio ? Colors.red : Colors.green,
onPressedFun: 1 == sfyc
? null
: () async {
int ret = -1;
print('等待复审提交确认');
await Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogHysh(
shjg: 0 == _selectedRadio ? hyc_text : fhyc_text,
title: '复审',
content:
'是否进行复审提交${tsjj && 0 == sfyc ? '、同时推送交警' : ''}?\n${1 == sfyc ? _sfcyTextTrue : ''}'),
),
)
.then((value) async {
print('value = $value');
if (value) {
print('用户已确认,开始处理复审提交!');
//复审接口增加是否延迟字段 sfyc (是否延迟)整型 必须 是否延误,0-正常 1-延误。延误状态的不推送
// 初审不用判断,sfyc 直接提交0即可。只有复审的时候才判断时间
// A、若在规定时间内,则 int sfyc = 0,审核完毕后正常推送交警。
// B、若超出规定时间,即当前时间>抓拍时间+间隔时间,则 sfyc = 1,不推送交警。
//设置 sfyc 和 tsjj
set_sfyc_tsjj(int.parse(listGetZpjl[widget.index]['zpsj']))
.then((value) async {
hyshContentFirstAudit(
widget.id,
widget.index,
mapHyshlx[hyshlx]['audit_workflow'],
topTabs_map['auditShuoming_Controller_List'][widget.index]
.text,
topTabs_map['auditTitle'][widget.index],
sfyc: sfyc,
).then((value) {
eventBus.fire(HycsDataUpdateEvent(
'${mapHyshlx[hyshlx]['text']}数据已更新'));
//必须等待审核过程完成后,再处理同时推送交警,否则推送交警总是失败
print('tsjj = $tsjj');
if (tsjj) {
print('before tsjjFun(widget.id, _plateAndID)');
String _plateAndID =
topTabs_map['car_number_List'].toString() +
'(ID:${widget.id.toString()})';
tsjjFun(widget.id, _plateAndID);
print('after tsjjFun(widget.id, _plateAndID)');
Fluttertoast.showToast(
msg: '$_plateAndID 已推送交警,请等待返回结果。',
gravity: ToastGravity.CENTER);
}
});
});
} else {
print('用户取消了复审提交');
}
});
Navigator.pop(context, ret);
},
width: 90.0,
height: 34.0), //'复审提交'
getBtnSizeX(
text: "取消",
onPressedFun: () async {
Navigator.pop(context);
},
width: 60.0,
height: 34.0), //'取消'
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
//_getShjgImage(widget.tabController, _selectedRadio, 35),
Container(
width: 35,
height: 35,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(_selectedRadio == 0
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
),
getBtnSizeX(
text: '初审提交',
fontColor: 0 == _selectedRadio ? Colors.red : Colors.green,
onPressedFun: 1 == sfyc
? null
: () async {
int ret = -1;
print('等待初审提交确认');
await Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogHysh(
shjg: 0 == _selectedRadio ? hyc_text : fhyc_text,
title: '初审',
content: '是否进行初审提交?'),
),
)
.then((value) async {
print('value = $value');
if (value) {
print('用户已确认,开始处理初审提交!');
//return;
hyshContentFirstAudit(
widget.id,
widget.index,
mapHyshlx[hyshlx]['audit_workflow'],
topTabs_map['auditShuoming_Controller_List'][widget.index]
.text,
topTabs_map['auditTitle'][widget.index],
sfyc: 0,
).then((value) {
eventBus.fire(
HycsDataUpdateEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
});
} else {
print('用户取消了初审提交');
}
});
Navigator.pop(context, ret);
},
width: 90.0), //'初审提交'
getBtnSizeX(
text: "取消",
onPressedFun: () async {
Navigator.pop(context);
},
width: 60.0), //'取消'
],
),
],
),
);
}
//5.3、得到审核结果组件
Widget getShjg(int index) {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(175),
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: my_marginLeft),
Text((widget.hyshlx == 'hyfh' ? '复审' : '初审') + '结果: ',
style: TextStyle(
fontSize: widget.fontSize,
color: 0 == _selectedRadio ? Colors.red : Colors.green)),
CustomRadioWidget(
value: 0,
title: mapHyshlx[hyshlx]['nick_text'] + "为黑烟车",
fontSize: widget.fontSize,
width: ScreenUtil().setWidth(400),
groupValue: _selectedRadio,
onChanged: (int value) {
_selectedRadio = value;
fh_hyc = true; //复审为黑烟车
tsjj = true; //同时推送交警
//黑烟初审数据审核Radio选项改变广播
eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
setState(() {});
print('selectedRadio = ${_selectedRadio.toString()}');
},
),
],
),
SizedBox(height: ScreenUtil().setHeight(15)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: my_marginLeft),
Text((widget.hyshlx == 'hyfh' ? '复审' : '初审') + '结果: ',
style: TextStyle(fontSize: widget.fontSize, color: Colors.white)),
CustomRadioWidget(
value: 1,
title: "非黑烟车",
fontSize: widget.fontSize,
width: ScreenUtil().setWidth(400),
groupValue: _selectedRadio,
onChanged: (int value) {
_selectedRadio = value;
fh_hyc = false; //复审为黑烟车
tsjj = false; //同时推送交警
//黑烟初审数据审核Radio选项改变广播
eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
setState(() {});
print('selectedRadio = ${_selectedRadio.toString()}');
},
),
],
),
],
),
);
}
//5.2、得到审核意见组件
Widget getShyj(int index) {
// return ConstrainedBox(
// constraints: BoxConstraints(
// minWidth: double.infinity, //宽度尽可能大
// //minHeight: _listTileHeight, //最小高度
// maxHeight: my_listTileHeight, //最大高度
// ),
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(120),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: <Widget>[
SizedBox(width: my_marginLeft),
Text((widget.hyshlx == 'hyfh' ? '复审' : '初审') + '意见: ',
style: TextStyle(
fontSize: my_fontSize, color: 0 == _selectedRadio ? Colors.red : Colors.green)),
Container(
alignment: Alignment(-1, 0),
height: 120,
//widthTrail = 400报错,360刚能显示,300换行,266
width: ScreenUtil().setWidth(775),
child: TextField(
//textAlign: TextAlign.right,
//style: TextStyle(fontSize: _fontSize, color: cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])].cpysFont),
//style: TextStyle(fontSize: _fontSize, color: cpysList[getIndexOfCpysList(colorText: myCpys)].cpysFont),
style: TextStyle(fontSize: my_fontSize),
textAlign: TextAlign.left,
decoration: InputDecoration(
hintText: '請輸入审核意见',
//border: InputBorder.none, //TextField去掉下划线
//contentPadding: EdgeInsets.only(right: 0),
//contentPadding: EdgeInsets.symmetric(vertical: my_textFieldHeight),
contentPadding: EdgeInsets.only(left: 4, right: 4), //这行代码是关键,设置这个之后,居中
//contentPadding: EdgeInsets.zero, //这行代码是关键,设置这个之后,居中
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[600]),
//borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(3),
),
),
controller: topTabs_map['auditShuoming_Controller_List'][index],
maxLines: 1,
minLines: 1,
//maxLengthEnforced: false,
//maxLength: 10,
enabled: true,
//利用控制器初始化文本
onChanged: (value) {
topTabs_map['auditShuoming_Controller_List'][index].text = value;
},
),
),
],
),
);
}
Widget getBtnSizeX(
{@required text, width = 70.0, height = 35.0, onPressedFun, fontColor = Colors.black}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text, style: TextStyle(color: fontColor)),
onPressed: onPressedFun,
),
);
}
}
class CustomRadioWidget<T> extends StatelessWidget {
final T value;
final String title;
final double fontSize;
final T groupValue;
final ValueChanged<T> onChanged;
final double width;
final double height;
CustomRadioWidget(
{this.value,
this.title = '',
this.fontSize = 16,
this.groupValue,
this.onChanged,
this.width = 25,
this.height = 25});
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(0),
child: GestureDetector(
onTap: () {
onChanged(this.value);
},
child: Container(
//alignment: Alignment(0, 0),
height: this.height,
width: this.width,
child: value == groupValue
? Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(Icons.radio_button_checked_rounded,
color: onChanged == null ? Colors.grey : Colors.blue),
),
SizedBox(width: title.isEmpty ? 0 : 2),
Text(
title,
style: TextStyle(
fontSize: fontSize,
color: onChanged == null ? Colors.grey : Colors.blue,
fontWeight: FontWeight.bold,
),
),
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(Icons.radio_button_unchecked_rounded,
color: onChanged == null ? Colors.grey : Colors.black),
),
SizedBox(width: title.isEmpty ? 0 : 2),
Text(title,
style: TextStyle(
fontSize: fontSize,
color: onChanged == null ? Colors.grey : Colors.black)),
],
),
),
),
);
}
}
+926
View File
@@ -0,0 +1,926 @@
//import '../../../widget/player_pro.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flustars/flustars.dart' as flustars; //该组件中有ScreenUtil
import 'package:flutter/material.dart';
import 'package:flutter_drag_scale/flutter_drag_scale.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/customDialogF.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/my_superplayer.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
//
import '../../../components/commonFun.dart';
//import 'package:hyzp_ybqx/widget/player_pro_new.dart';
import '../../../components/dioFun.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
class TsjjContentNew extends StatefulWidget {
TsjjContentNew({
@required this.hyshlx,
@required this.title,
this.indexRecord,
this.id,
Key key,
}) : super(key: key);
String title;
int indexRecord = 0;
int id = -1;
String hyshlx;
_LoginPageState createState() => _LoginPageState();
}
//用TabController实现顶部tab切换
class _LoginPageState extends State<TsjjContentNew> with SingleTickerProviderStateMixin {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
dispose() {
super.dispose();
}
BuildContext _context;
String _title = '';
//flutter_screenUtil 4.x 用法,ScreenUtil.screenWidth (sdk>=2.6 : 1.sw) //设备宽度
double _screenWidth = 1.sw;
double _marginLeft = 8;
double _marginCenter = 70;
double _fontSize = 16;
double _widthLeft = 40; // = _screenWidth / 3;
double _iconSize = 18;
double _stampSize = 100;
double _listTileHeight = 30;
double _marginVer = 10;
Color _iconColor = Colors.blue;
Map _mapTsjjGetTsStatus = {};
void initState() {
//黑烟审核推送交警Checkbox改变事件
eventBus.on<HycsDataAuditSfyc>().listen((event) {
print(event.str);
try_setState(); //避免如下异常报错
});
_widthLeft = _screenWidth / 2;
getListFlields();
_context = context;
super.initState();
}
Map _mapGetTsjjGetData = {
"id": 1203,
"plate_id": "川QS9661",
"plate_color": "蓝色",
"zpsj": 1612770967,
"yjxx_id": "1379",
"workflow": 2,
"video_url": "video/9_6063_20210208_155607_川QS9661.mp4",
"pic_url": "/wwwroot/admin/Api/wwwroot/public/uploads/926f5168f1fe109a9b8ec88dcac7ac2c.jpg",
"clfl": "皮卡车",
"dwip": "172.16.3.9",
"dwms": "宜长路出城方向",
"lgmzs": 3,
"jczxd": "863",
"sfhy": "黑烟车",
};
double _radioImage = 9 / 16;
Widget imageWztp;
getListFlields() async {
_mapGetTsjjGetData = await getWzxxItemData(widget.id); //获取指定id的违章信息返回 _mapGetTsjjGetData
print('_mapGetTsjjGetData = ${_mapGetTsjjGetData}');
await getShenheData(widget.id); //获取指定id的审核信息存入 listGetShenheData
await getMapGetShenheData(); //从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
//Tab切换时,设置 sfyc 和 tsjj,只处理当前选中的抓拍记录 _tabController.index,zpsj抓拍时间
set_sfyc_tsjj(_mapGetTsjjGetData['zpsj']);
// 获取推送交警状态信息
// tsjjGetTsStatus返回字段 类型 说明
// id 整型 违章记录ID
// checkid 整型 推送的抓拍记录ID
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 3-推送成功
// 20210529更新:
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 2-推送成功 | 3-规定时间内已有违章记录,本次不推送 | 4-现场登记,不推送
// ts_time 字符串 推送时间
//Future tsjjGetTsStatus(int _wzxxID)
_mapTsjjGetTsStatus = await tsjjGetTsStatus(widget.id);
print('_mapTsjjGetTsStatus = $_mapTsjjGetTsStatus');
// 获取网络图片尺寸
flustars.WidgetUtil.getImageWH(url: getMediaUrl(_mapGetTsjjGetData['pic_url'])).then((rect) {
if (null != rect) {
_radioImage = rect.height / rect.width;
}
});
imageWztp = getWztp(); //得到违章图片
//下面读取的是全局数据,该模块不需要修改
// 川Q565H4
try {
//_title = '违章黑烟车详情(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})id:${listHycsGetList2[widget.indexRecord]['id']}';
//_title = '违章黑烟车(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length}):${listHycsGetList2[widget.indexRecord]["plate_id"]}(${listHycsGetList2[widget.indexRecord]["plate_color"]})';
_title = '推送交警详情(${(widget.indexRecord + 1).toString()} / ${listHycsGetList2.length})';
setState(() {});
} catch (e) {}
}
// 使用 cached_network_image 插件实现网络图片缓存
// 使用 flutter_drag_scale 实现可缩放可拖拽双击放大的图片功能。PhotoView插件不好用,有问题
Widget getNetworkImage(String url) {
return CachedNetworkImage(
imageUrl: url,
alignment: Alignment.topCenter,
imageBuilder: (context, imageProvider) => DragScaleContainer(
doubleTapStillScale: true, child: Image(image: imageProvider)
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
// imageBuilder: (context, imageProvider) => PhotoView(
// imageProvider: imageProvider,
// ),
//placeholder: (context, url) => CircularProgressIndicator(),
placeholder: (context, url) =>
getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
// 167 50 3.34
Widget getLgmzs(int lgmzs, {double width = 127, double height = 127}) {
int _rgb = (255 * (5 - lgmzs)) ~/ 5;
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 4),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('$lgmzs级${lgmzs * 20}%', style: TextStyle(fontSize: 10)),
//SizedBox(height: 0),
Container(
width: ScreenUtil().setWidth(66),
height: ScreenUtil().setHeight(66),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Color.fromRGBO(_rgb, _rgb, _rgb, 1.0),
borderRadius: new BorderRadius.circular(0),
),
)
],
),
),
Positioned(
top: ScreenUtil().setHeight(4),
child: Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height - 8),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: (lgmzs == _mapGetTsjjGetData['lgmzs'])
? Colors.red
: Color.fromRGBO(244, 244, 244, 1),
width: 2),
//color: Colors.lightBlue,
borderRadius: new BorderRadius.circular(3.0),
),
),
)
],
);
}
//1、得到格林曼黑度标准和视频播放按钮组件
Widget getHdAndPlay() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getLgmzs(0),
getLgmzs(1),
getLgmzs(2),
getLgmzs(3),
getLgmzs(4),
getLgmzs(5, width: 153),
getIconBtnSizeX(
height: 104,
//getIconBtnSizeX 中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 168,
text: "视频",
textSize: 12,
circular: 4,
color: Color.fromRGBO(52, 157, 237, 1),
onTop: () async {
if (Playing) {
//禁止同时启动两次播放器
return;
}
Playing = true; //禁止同时启动两次播放器
urlnew = getMediaUrl(_mapGetTsjjGetData['video_url']);
//获取视频地址失败
if (!isVideoUrl(urlnew)) {
return;
}
Navigator.of(_context).push(MaterialPageRoute(
builder: (context) => SuperPlayerPage(
loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
url: urlnew,
title:
'违章视频: ${_mapGetTsjjGetData["plate_id"]}\n${_mapGetTsjjGetData['dwms']}')));
// Navigator.of(_context).push(MaterialPageRoute(
// builder: (context) => PlayerProNew(
// loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
// url: urlnew,
// title:
// '违章视频: ${_mapGetTsjjGetData["plate_id"]}\n${_mapGetTsjjGetData['dwms']}')));
},
),
SizedBox(width: ScreenUtil().setWidth(15)),
],
);
}
//2、得到违章图片组件
Widget getWztp() {
//ratioList[index] = 0.5714285714285714
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(1022),
//height: ScreenUtil().setHeight(639),
//height: ScreenUtil().setHeight(22 + 1022 * _radioImage),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
decoration: BoxDecoration(
//color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
Positioned(
//left: ScreenUtil().setWidth(25),
top: ScreenUtil().setHeight(25),
child: Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
child: getNetworkImage(getMediaUrl(_mapGetTsjjGetData['pic_url'])),
),
)
],
);
}
// void printScreenInformation() {
// print('Device width dp:${1.sw}dp');
// print('Device height dp:${1.sh}dp');
// print('Device pixel density:${ScreenUtil().pixelRatio}');
// print('Bottom safe zone distance dp:${ScreenUtil().bottomBarHeight}dp');
// print('Status bar height dp:${ScreenUtil().statusBarHeight}dp');
// print('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}');
// print(
// 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}');
// print('System font scaling:${ScreenUtil().textScaleFactor}');
// print('0.5 times the screen width:${0.5.sw}dp');
// print('0.5 times the screen height:${0.5.sh}dp');
// }
void printScreenInformation() {
print('ScreenUtil().screenWidth = ${ScreenUtil().screenWidth}');
print('设备宽度:${1.sw}dp');
print('"1.w" = ${1.w}');
print('"1.sw" = ${1.sw}');
print('设备高度:${1.sh}dp');
print('设备的像素密度:${ScreenUtil().pixelRatio}');
print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');
print('状态栏高度:${ScreenUtil().statusBarHeight}dp');
print('实际宽度的dp与设计稿px的比例:${ScreenUtil().scaleWidth}');
print('实际高度的dp与设计稿px的比例:${ScreenUtil().scaleHeight}');
print('宽度和字体相对于设计稿放大的比例:${ScreenUtil().scaleWidth * ScreenUtil().pixelRatio}');
print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight * ScreenUtil().pixelRatio}');
print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');
print('屏幕宽度的0.5:${0.5.sw}dp');
print('屏幕高度的0.5:${0.5.sh}dp');
}
//3、得到违章图片说明信息组件
Widget getWztpSmxx() {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(270),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getWzxxPart1(),
getWzxxPart2(),
getWzxxPart3(),
],
),
);
}
// I/flutter (22989): ScreenUtil().screenWidth = 360.0
// I/flutter (22989): 设备宽度:360.0dp
// I/flutter (22989): "1.w" = 0.3333333333333333
// I/flutter (22989): "1.sw" = 360.0
// I/flutter (22989): 设备高度:640.0dp
// I/flutter (22989): 设备的像素密度:3.0
// I/flutter (22989): 底部安全区距离:0.0dp
// I/flutter (22989): 状态栏高度:24.0dp
// I/flutter (22989): 实际宽度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 实际高度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 宽度和字体相对于设计稿放大的比例:1.0
// I/flutter (22989): 高度相对于设计稿放大的比例:1.0
// I/flutter (22989): 系统的字体缩放比例:1.0
// I/flutter (22989): 屏幕宽度的0.5:180.0dp
// I/flutter (22989): 屏幕高度的0.5:320.0dp
//3、得到违章信息组件1:车牌号码、车牌颜色
//车牌颜色Map cpysMap = {
// '蓝色': cpysItem(
// cpysText: '蓝色',
// cpysBackground: Colors.blue,
// cpysFont: Colors.white,
// cpysBorder: Colors.orange),
// }
Widget getWzxxPart1() {
//printScreenInformation();
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getTitleText('车牌号码:'),
getBoderText(_mapGetTsjjGetData['plate_id'].toString(),
width: ScreenUtil().setWidth(1022 / 3.2)),
SizedBox(width: ScreenUtil().setWidth(_marginCenter)),
getTitleText('颜色:'),
getBoderText(_mapGetTsjjGetData['plate_color'], width: ScreenUtil().setWidth(1022 / 4.8)),
],
);
}
Widget getTitleText(String text, {double fontSize = 16, int lines = 1, Color color}) {
return Text(text,
style: TextStyle(fontSize: fontSize, color: color),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
maxLines: lines);
}
Widget getTrailText(String text, {double fontSize = 16, double off = 0}) {
return Container(
width: ScreenUtil().setWidth(1022) - _widthLeft - off - (2 * _marginLeft),
child: Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
);
}
Widget getBoderText(String text, {double width = 40}) {
cpysItem _cpysItem = cpysMap[_mapGetTsjjGetData['plate_color']];
return Container(
//color: _cpysItem.cpysBackground,
alignment: Alignment(0, -1),
width: width,
decoration: BoxDecoration(
border: Border.all(color: _cpysItem.cpysBorder, width: 2),
color: _cpysItem.cpysBackground,
borderRadius: BorderRadius.circular(3),
),
child: Padding(
padding: EdgeInsets.only(bottom: 3),
child: Text(text,
style: TextStyle(fontSize: _fontSize, color: _cpysItem.cpysFont),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
),
);
}
//I/flutter (17555): _mapGetTsjjGetData = {
// id: 1222, plate_id: 川Q736X2, plate_color: 蓝色, zpsj: 1612857077, yjxx_id: 1399, workflow: 999,
// video_url: video/9_6063_20210209_155117_川Q736X2.mp4,
// pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/9d2f45fd24b41f2b94abe42b30970d75.jpg,
// clfl: 集装箱卡车, dwip: 172.16.3.9, dwms: 宜长路出城方向, lgmzs: 3, jczxd: 994, sfhy: 黑烟车
// }
Widget getIcon(IconData _iconData) {
return Container(
width: _iconSize - 2,
height: _iconSize,
child: Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(_iconData, size: _iconSize, color: _iconColor),
),
);
}
//4、得到违章信息组件2:抓拍时间组件
Widget getWzxxPart2() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - _marginLeft,
child: getTitleText(
'抓拍时间:' +
getDate(
(_mapGetTsjjGetData['zpsj'] is int)
? _mapGetTsjjGetData['zpsj']
: int.parse(_mapGetTsjjGetData['zpsj']),
),
),
),
],
);
}
Widget getWzxxPart3() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - _marginLeft,
child: getTitleText('抓拍地点:' + _mapGetTsjjGetData['dwms']),
),
],
);
}
//4、得到审核信息组件
Widget getShxx() {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(380),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getWzxxPart4(),
getWzxxPart5(),
getWzxxPart6(),
],
),
);
}
//6、得到审核信息组件4:违章类型、格林曼黑度组件
Widget getWzxxPart4() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: _widthLeft,
child: getTitleText('违章类型:' + _mapGetTsjjGetData['sfhy']),
),
SizedBox(width: _marginLeft),
//getIcon(Icons.location_on_outlined),
Container(
width: _iconSize,
height: _iconSize,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(image: AssetImage("assets/images/hyc.png"), fit: BoxFit.contain),
),
alignment: Alignment.center,
//child:
),
getTrailText(':' + _mapGetTsjjGetData['lgmzs'].toString(), off: _iconSize),
],
);
}
//从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
//7、得到审核信息组件5:初审人员,初审时间
Widget getWzxxPart5() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: 300,
child: getTitleText('初审人员:' + mapGetHycsShenheData['uname']),
),
// SizedBox(width: _marginLeft),
// getIcon(Icons.query_builder),
// getTrailText(':' + mapGetHycsShenheData['addtime'], off: _iconSize),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: 300,
child: getTitleText('初审时间:' + mapGetHycsShenheData['addtime']),
),
],
)
],
);
}
//8、得到审核信息组件6:复审人员,复审时间
Widget getWzxxPart6() {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: 300,
child: getTitleText('复审人员:' + mapGetHyfhShenheData['uname']),
),
// SizedBox(width: _marginLeft),
// getIcon(Icons.query_builder),
// getTrailText(':' + mapGetHycsShenheData['addtime'], off: _iconSize),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: 300,
child: getTitleText('复审时间:' + mapGetHyfhShenheData['addtime']),
),
],
)
],
);
}
//5、得到推送交警状态组件
Widget getTsjjStatus() {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(1 == _mapTsjjGetTsStatus['tszt'] ||
2 == _mapTsjjGetTsStatus['tszt'] ||
2 != _mapTsjjGetTsStatus['tszt'] && 1 == sfyc
? 170
: 90),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getWzxxPart7(),
],
),
);
}
//7、得到推送交警状态信息组件7:推送状态
// 20210529更新:
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 2-推送成功 | 3-规定时间内已有违章记录,本次不推送 | 4-现场登记,不推送
//_mapTsjjGetTsStatus['tszt']
Widget getWzxxPart7() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - _marginLeft,
child: Container(
child: getTitleText(
'推送状态:' +
mapTsztText[_mapTsjjGetTsStatus['tszt']] +
(1 == _mapTsjjGetTsStatus['tszt'] || 2 == _mapTsjjGetTsStatus['tszt']
? '\n推送时间:${getDate((_mapTsjjGetTsStatus['ts_time'] is int) ? _mapTsjjGetTsStatus['ts_time'] : int.parse(_mapTsjjGetTsStatus['ts_time']))}'
: '') +
(0 == _mapTsjjGetTsStatus['tszt'] && 1 == sfyc
? ',但已超时。当前时间 > 抓拍时间 + 审核间隔,不能推送交警!'
: ''),
lines: 2,
color: Colors.blue),
),
),
],
);
}
//10、得到推送交警确认组件
Widget getTsjjQr() {
Widget qxButton = getBtnSizeX(
text: "取消",
onPressedFun: showMoreWidget
? null
: () async {
Navigator.pop(context);
},
width: 90.0);
// App.Car_Hyc.GetTs接口返回值说明中没有tszt为2,但许多记录返回值都是2,返回值为2是否是推送成功?
// App.Car_Hyc.GetTs接口返回值说明有误,返回值为2表示推送成功、而不是3
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 3-推送成功
// 20210529更新:
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 2-推送成功 | 3-规定时间内已有违章记录,本次不推送 | 4-现场登记,不推送
//_mapTsjjGetTsStatus['tszt']
return Container(
//padding: EdgeInsets.only(top: ScreenUtil().setWidth(6)),
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(155),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: 2 == _mapTsjjGetTsStatus['tszt']
? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text('已推送', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)),
SizedBox(width: 2),
Padding(
padding: EdgeInsets.only(top: 3),
child: Icon(
Icons.check,
size: 18,
),
),
],
),
qxButton, //'取消'
],
)
: 1 == sfyc
? Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(text: '已超时', onPressedFun: null, width: 90.0), //'复审提交'
qxButton, //'取消'
],
)
: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(
text: '推送',
onPressedFun: showMoreWidget
? null
: () async {
print('等待推送交警确认');
await Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogF(title: '推送确认', content: '是否推送交警?'),
),
)
.then((value) async {
print('value = $value');
if (value) {
print('用户已确认,开始处理推送交警!');
//return;
print('before tsjjFun(widget.id)');
showMoreWidget = true;
try_setState();
String _plateAndID = _mapGetTsjjGetData['plate_id'].toString() +
'(ID:${widget.id.toString()})';
tsjjFun(widget.id, _plateAndID);
showMoreWidget = false;
try_setState();
Fluttertoast.showToast(
msg: '$_plateAndID 已推送交警,请等待返回结果。',
gravity: ToastGravity.CENTER);
} else {
print('用户取消了推送交警操作');
}
});
//Unhandled Exception: type 'String' is not a subtype of type 'int' of 'result'
Navigator.pop(context, -1);
},
width: 90.0), //'复审提交'
qxButton, //'取消'
],
),
);
}
bool showMoreWidget = false;
@override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
//设置title的左边距
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
//1.1、返回按钮
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(_title,
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 30),
],
),
),
),
),
body: null == imageWztp
// 显示加载中的圈圈
? getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0)
: Stack(
children: [
//SizedBox.shrink() 创建父类允许最小尺寸的约束Box
showMoreWidget
? Align(
alignment: Alignment(0, 0.8),
child: Container(
height: 200,
width: 200,
child: getMoreWidget2(
text: '加载中...',
color: Colors.red,
size: 40.0,
strokeWidth: 3.0), //显示加载中的圈圈,
),
)
: SizedBox.shrink(),
KeyboardAvoider(
autoScroll: true,
child: Container(
color: Color.fromRGBO(244, 244, 244, 1),
child: Column(
children: <Widget>[
//1、得到格林曼黑度标准和视频播放按钮组件
getHdAndPlay(),
//2、得到违章图片组件
//getWztp(),
imageWztp,
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//3、得到违章图片说明信息组件
getWztpSmxx(),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//4、得到审核信息组件
getShxx(),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//5、得到推送交警状态组件
getTsjjStatus(),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//9、得到推送交警确认组件
getTsjjQr(),
SizedBox(height: 10),
],
),
),
),
Positioned(
//alignment: Alignment(0.9, 0.35),
//alignment: Alignment(0.8, 0.48),
left: ScreenUtil().setWidth(80),
top: ScreenUtil().setHeight(1015),
child: Container(
//alignment: Alignment(0.5, -0.5),
width: _stampSize,
height: _stampSize,
//color: Colors.black12,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
image: AssetImage("assets/images/jkzx_stamp.png"), fit: BoxFit.contain),
),
//child:
),
),
Positioned(
//alignment: Alignment(0.9, 0.35),
//alignment: Alignment(0.8, 0.48),
right: ScreenUtil().setWidth(80),
top: ScreenUtil().setHeight(1015),
child: Container(
//alignment: Alignment(0.5, -0.5),
width: _stampSize,
height: _stampSize,
//color: Colors.black12,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
image: AssetImage("assets/images/hyc.png"), fit: BoxFit.contain),
),
//child:
),
),
],
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
@@ -0,0 +1,676 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/JdButton.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
import '../../../components/commonFun.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../widget/DropdownItem.dart';
class LedXsxxContent extends StatefulWidget {
LedXsxxContent({
@required this.sbgllx, //sbgllx: 'led_xsxx', //设备管理类型:LED显示信息
@required this.title,
@required this.id,
Key key,
}) : super(key: key);
String title;
int id;
String sbgllx;
_LedXsxxPageState createState() => _LedXsxxPageState();
}
//用TabController实现顶部tab切换
class _LedXsxxPageState extends State<LedXsxxContent> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
dispose() {
super.dispose();
}
String _title = '';
//flutter_screenUtil 4.x 用法,ScreenUtil.screenWidth (sdk>=2.6 : 1.sw) //设备宽度
double _screenWidth = 1.sw;
double _marginLeft = 15;
double _marginCenter = 5;
double _marginCenterHeight = 20;
double _widgetHeight = 35;
double _fontSize = 16;
double _widthLeft = 40; // = _screenWidth / 3;
double _iconSize = 18;
double _stampSize = 100;
double _listTileHeight = 30;
Color _iconColor = Colors.blue;
double _titleWidth = 130;
//处理全部记录
bool _modifyAll = false;
void initState() {
super.initState();
// listLedXsxxGetList2.clear();
// ///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
// getPageList().then((value) {
// listLedXsxxGetList2 = value;
// //按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
// });
///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据,返回 list
///获取点位信息数据
listDwinfoGetList2.clear();
getThePageList(theHyshlx: 'dwxx').then((value) {
listDwinfoGetList2 = value;
print('listDwinfoGetList2 = \n$listDwinfoGetList2');
getListFlields();
});
//listDwinfoGetList2 = [{
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆"
//},
//{
// "id": 2,
// "dwip": "172.16.3.2",
// "dwmc": "宜飞路",
// "dwbh": 2,
// "dwinfo": "宜宾南收费站宜飞路入城方向",
// "dwzb": "104.589904|28.787078",
// "dwms": "宜宾南收费站宜飞路入城方向,识别屏山、菜坝入城排放黑烟车辆"
//},];
_widthLeft = _screenWidth / 2.6;
//监听 选择LED点位 更新事件
eventBus.on<SelectLedDwUpdateEvent>().listen((event) async {
//获取用户选择项对应的记录id
widget.id = _listItems.indexOf(event.selectedValue);
print('原生 widget.id = ${widget.id}');
if (widget.id < 1) {
_modifyAll = true; //处理全部记录
widget.id = 1;
} else {
_modifyAll = false; //处理全部记录
}
print('widget.id = ${widget.id}');
//刷新页面数据
await getListFlields();
//刷新 显示违章记录 Dropdown
// print('_mapGetLedXsxxGetData = ${_mapGetLedXsxxGetData}');
// print('_mapGetLedXsxxGetData["xsts"] = ${_mapGetLedXsxxGetData["xsts"]}');
// print(
// 'getWzjlString(_mapGetLedXsxxGetData["xsts"]) = ${getWzjlString(_mapGetLedXsxxGetData["xsts"])}');
eventBus.fire(SelectWzjlUpdateEvent(
'external_SelectWzjlUpdateEvent', getWzjlString(_mapGetLedXsxxGetData["xsts"])));
try_setState(); //避免异常报错
print(event.str);
});
//监听 选择显示违章记录 更新事件
eventBus.on<SelectWzjlUpdateEvent>().listen((event) async {
print('SelectWzjlUpdateEvent: ${event.str}');
print('SelectWzjlUpdateEvent: ${event.selectedValue}');
_selectedValue = event.selectedValue;
_xsts = getWzjlCount(event.selectedValue);
//只响应内部发送的'insider_SelectWzjlUpdateEvent'
//不响应外部发送的'external_SelectWzjlUpdateEvent'
if (event.str == 'external_SelectWzjlUpdateEvent') {
//刷新页面数据
try_setState(); //避免异常报错
}
});
}
//App.Car_Led.Get接口获取的记录数据结构(比App.Car_Led.GetList接口获取的丰富)
Map _mapGetLedXsxxGetData = {
"id": 2,
"dwip": "172.16.3.2",
"xsnr": "绿水青山就是金山银山 宜宾市生态环境局宣。",
"xsts": 0, //显示抓拍到的多少条违章记录
"stime": "07:00",
"etime": "23:00",
"addtime": "2021-01-20 10:16:07",
"updatetime": "2021-02-13 11:48:51"
};
//Web管理平台LED点位名称。除第一项外,估计后面都按ID号排列
// 全部
// 1 '江北振兴大道',
// 2 '宜飞路',
// 3 '宜宾南收费站',
// 4 '一曼路',
// 5 '柏溪收费站',
// 6 '七星路万达广场',
// 7 '宜宾财政局',
// 8 '宜威路南广镇',
// 9 '宜长路',
// 10 '宜南快速通道',
// 11 '观斗山隧道',
// 12 '大麦坝',
// 13 '外江路',
//LED点位名称List,除第一项外,后面都按ID号排列
List _listItems = [
// '全部',
// '1、江北振兴大道',
// '2、宜飞路',
// '3、宜宾南收费站',
// '4、一曼路',
// '5、柏溪收费站',
// '6、七星路万达广场',
// '7、宜宾财政局',
// '8、宜威路南广镇',
// '9、宜长路',
// '10、宜南快速通道',
// '11、观斗山隧道',
// '12、大麦坝',
// '13、外江路',
];
String _selectedValue = '不显示';
int _xsts = 0;
String _startTime = '07:00';
String _endTime = '23:00';
String _ledMessage = '绿水青山就是金山银山 宜宾市生态环境局宣。';
//App.Car_Led.Get接口获取的记录数据结构(比App.Car_Led.GetList接口获取的丰富)
// Map _mapGetLedXsxxGetData = {
// "id": 2,
// "dwip": "172.16.3.2",
// "xsnr": "绿水青山就是金山银山 宜宾市生态环境局宣。",
// "xsts": 0, //显示抓拍到的多少条违章记录
// "stime": "07:00",
// "etime": "23:00",
// "addtime": "2021-01-20 10:16:07",
// "updatetime": "2021-02-13 11:48:51"
// };
Future getListFlields() async {
//实时更新_listItems内容
_listItems = ['全部']; //LED点位名称List,除第一项外,后面都按ID号排列
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
_listItems.add('${i + 1}、${listDwinfoGetList2[i]['dwmc']}');
}
print('_listItems = $_listItems');
//获取指定id的LED记录数据返回 _mapGetLedXsxxGetData
_mapGetLedXsxxGetData = await getLedXsxxGetData(id: widget.id, theSbgllx: widget.sbgllx);
//printWrapped('_mapGetLedXsxxGetData = ${_mapGetLedXsxxGetData}');
//_mapGetLedXsxxGetData = {
// "id": 1,
// "dwip": "172.16.3.1",
// "xsnr": "绿水青山就是金山银山 宜宾市生态环境局宣。",
// "xsts": 0,
// "stime": "07:00",
// "etime": "23:00",
// "addtime": "2021-01-06 00:59:43",
// "updatetime": "2021-02-03 19:57:55"
// };
_xsts = _mapGetLedXsxxGetData['xsts'];
_ledMessage = _mapGetLedXsxxGetData['xsnr'];
_startTime = _mapGetLedXsxxGetData['stime'];
_endTime = _mapGetLedXsxxGetData['etime'];
try {
// _title =listDwinfoGetList2
// '${widget.title}(${(getIndex(widget.id) + 1).toString()} / ${listLedXsxxGetList2.length})id:${widget.id.toString()}';
//_title = '${widget.title}(${widget.id.toString()} / ${listDwinfoGetList2.length})id:${widget.id.toString()}';
//_title = '${widget.title}(${widget.id.toString()} / ${listDwinfoGetList2.length})${listDwinfoGetList2[widget.id - 1]['dwmc']}';
_title = '${widget.title}(${widget.id.toString()} / ${listDwinfoGetList2.length})';
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
// List listLedXsxxGetData = [];
// for(int i = 0; i < 13; i++) {
// listLedXsxxGetData.add(await getLedXsxxGetData(i + 1));
// }
// print('listLedXsxxGetData = \nlistLedXsxxGetData');
}
//获取 listLedXsxxGetList2 中ID号为 _id 的索引号
// int getIndex(int _id) {
// int len = listLedXsxxGetList2.length;
// int _index;
// for (_index = 0; _index < len; _index++) {
// if (listLedXsxxGetList2[_index]['id'] == _id) {
// break;
// }
// }
// return _index;
// }
Widget getTitleText(String text, {double fontSize = 16}) {
return Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis);
}
Widget getSizeText(String text, {double fontSize = 16, double width = 100, double top = 0}) {
return Container(
margin: EdgeInsets.only(top: top),
width: width,
child: Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
);
}
Widget getIcon(IconData _iconData) {
return Container(
width: _iconSize - 2,
height: _iconSize,
child: Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(_iconData, size: _iconSize, color: _iconColor),
),
);
}
//5、得到LED显示信息确认组件
Widget getLedQr() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
JdButton(
height: 126,
//JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 350,
text: "更新",
color: Color.fromRGBO(45, 202, 115, 1),
onTop: () {
printWrapped('_message = ${_ledMessage}');
print('_xsts = ${_xsts}');
print('_startTime = ${_startTime}');
print('_endTime = ${_endTime}');
//updateLedData({@required int id, @required String theSbgllx, @required Map map})
//_modifyAll = true; //id = -1,处理全部记录
updateLedData(id: _modifyAll ? -1 : widget.id, theSbgllx: 'led_update', map: {
'xsnr': _ledMessage,
'xsts': _xsts,
'stime': _startTime,
'etime': _endTime,
});
Navigator.pop(context);
},
),
JdButton(
height: 126,
//JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 350,
text: "取消",
color: Color.fromRGBO(43, 163, 255, 1),
onTop: () {
Navigator.pop(context);
},
),
],
);
}
//得到LED信息页面组件
//1、得到 选择LED点位 组件
Widget getSelectLedDw() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getSizeText('选择点位:', width: _titleWidth),
//SizedBox(width: _marginCenter),
//Expanded(child: SizedBox.shrink()),
DropdownItem(
listItems: _listItems,
//初始值 initValue 必须是 listItems 中的已有元素
initValue: _listItems[widget.id],
dropdownEvent: 'SelectLedDwUpdateEvent',
width: ScreenUtil().setWidth(590),
height: _widgetHeight,
), //SizedBox(width: _marginLeft),
SizedBox(width: _marginLeft),
],
);
}
//2、得到选择 显示违章记录 组件
Widget getSelectWzjl() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getSizeText('显示违章记录:', width: _titleWidth),
// Expanded(child: SizedBox.shrink()),
DropdownItem(
listItems: _listItemsWzjl,
initValue: getWzjlString(_xsts),
width: ScreenUtil().setWidth(590),
height: _widgetHeight,
dropdownEvent: 'SelectWzjlUpdateEvent',
),
SizedBox(width: _marginLeft),
],
);
}
List _listItemsWzjl = [
'不显示',
'显示3条',
'显示5条',
'显示10条',
];
//通过违章信息的条数得到显示的字符串
String getWzjlString(int wzjlCount) {
String _wzjlString = '';
switch (wzjlCount) {
case 0:
_wzjlString = _listItemsWzjl[0];
break;
case 3:
_wzjlString = _listItemsWzjl[1];
break;
case 5:
_wzjlString = _listItemsWzjl[2];
break;
case 10:
_wzjlString = _listItemsWzjl[3];
break;
default:
break;
}
return _wzjlString;
}
//通过字符串得到显示违章信息的条数
int getWzjlCount(String wzjlString) {
int _wzjlCount = -1;
switch (wzjlString) {
case '不显示':
_wzjlCount = 0;
break;
case '显示3条':
_wzjlCount = 3;
break;
case '显示5条':
_wzjlCount = 5;
break;
case '显示10条':
_wzjlCount = 10;
break;
default:
break;
}
return _wzjlCount;
}
//3、得到 启用时段 组件
Widget getOpenTime() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getSizeText('启用时段:', width: _titleWidth),
//SizedBox(width: _marginCenter),
getInBox(0, _widgetHeight), //whichTime:0为_startTime,1为_endTime
Text(' - '),
getInBox(1, _widgetHeight), //whichTime:0为_startTime,1为_endTime
],
);
}
//4、得到 显示信息 组件
Widget getLedMessage(double _width, double _height) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getSizeText('显示信息:', width: _titleWidth, top: 2),
],
),
SizedBox(height: ScreenUtil().setHeight(10)),
Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
getInBoxMsg(_width, _height), //whichTime:0为_startTime,1为_endTime
],
),
],
);
}
//显示信息 输入框
Widget getInBoxMsg(double _width, double _height) {
return ConstrainedBox(
constraints: BoxConstraints(
minHeight: ScreenUtil().setHeight(_height),
maxHeight: ScreenUtil().setHeight(_height),
minWidth: ScreenUtil().setWidth(_width),
maxWidth: ScreenUtil().setWidth(_width),
),
child: TextField(
keyboardType: TextInputType.multiline,
maxLines: 10,
//不限制行数
textAlign: TextAlign.justify,
style: TextStyle(fontSize: my_fontSize),
decoration: InputDecoration(
hintText: '请输入LED显示信息',
contentPadding: EdgeInsets.only(top: 4, left: 8, bottom: 4, right: 8),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(3.0)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(3.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(3),
borderSide: BorderSide(
color: Colors.grey,
width: 2.0,
),
),
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(3.0),
// borderSide: BorderSide(color: Colors.grey, width: 0)),
),
controller: TextEditingController.fromValue(TextEditingValue(
text: _ledMessage,
// 保持光标在最后
// selection: TextSelection.fromPosition(
// TextPosition(affinity: TextAffinity.downstream, offset: _message.length))
)),
enabled: true,
onChanged: (value) {
_ledMessage = value;
printWrapped(_ledMessage);
},
),
);
}
//whichTime:0为_startTime,1为_endTime
Widget getInBox(int _whichTime, double _height) {
return Container(
alignment: Alignment(0, 0),
height: _height,
width: 90,
// decoration: BoxDecoration(
// border: Border.all(color: Colors.grey, width: 2),
// borderRadius: BorderRadius.all(Radius.circular(3.0)),
// ),
child: TextField(
textAlign: TextAlign.center,
style: TextStyle(fontSize: my_fontSize),
decoration: InputDecoration(
hintText: _whichTime == 0 ? '启用时间' : '关闭时间',
contentPadding: EdgeInsets.all(0),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(3.0)),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey, width: 2.0),
borderRadius: BorderRadius.circular(3.0)),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(3),
borderSide: BorderSide(
color: Colors.grey,
width: 2.0,
),
),
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(3.0),
// borderSide: BorderSide(color: Colors.grey, width: 0)),
),
controller: TextEditingController.fromValue(TextEditingValue(
text: (_whichTime == 0 ? _startTime : _endTime),
// 保持光标在最后
selection: TextSelection.fromPosition(TextPosition(
affinity: TextAffinity.downstream,
offset: (_whichTime == 0 ? _startTime : _endTime).length)))),
enabled: true,
onChanged: (value) {
if (_whichTime == 0) {
_startTime = value;
} else {
_endTime = value;
}
},
),
);
}
String _sizedropDown = 'brown';
@override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(_title,
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 30),
],
),
),
),
),
body: _listItems.isEmpty || _mapGetLedXsxxGetData == null
? getMoreWidget(color: Colors.grey)
: KeyboardAvoider(
autoScroll: true,
child: Container(
child: Column(
children: <Widget>[
//1、得到选择LED点位组件
SizedBox(height: _marginCenterHeight),
getSelectLedDw(),
Divider(height: _marginCenterHeight),
//2、得到选择 显示违章记录 组件
getSelectWzjl(),
Divider(height: _marginCenterHeight),
//3、得到 启用时段 组件
getOpenTime(),
Divider(height: _marginCenterHeight),
//4、得到 显示信息 组件
getLedMessage(980, 570),
Divider(height: _marginCenterHeight),
SizedBox(height: _marginCenterHeight),
//5、得到Led确认组件
getLedQr(),
SizedBox(height: _marginCenterHeight),
],
),
),
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
@@ -0,0 +1,568 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'led_xsxx_content.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../components/commonFun.dart';
import '../../../services/EventBus.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import '../../../components/doJSON.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//LedXsxx是本项目中“LED显示信息”的统一缩写
class LedXsxxGetList extends StatefulWidget {
//hyshlx为黑烟审核类型,处理'LedXsxx'LED显示信息。mapHyshlx[hyshlx]获取为各种类型的设置数据
LedXsxxGetList({this.sbgllx = 'led_xsxx', Key key}) : super(key: key);
String sbgllx;
_LedXsxxPageState createState() => _LedXsxxPageState();
}
class _LedXsxxPageState extends State<LedXsxxGetList> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void dispose() {
_controller.dispose(); //销毁控制器
super.dispose();
}
@override
void initState() {
hyshlx = widget.sbgllx;
iPage = 0;
listLedXsxxGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList().then((value) {
listLedXsxxGetList2 = value;
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
});
///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据,返回 list
///获取点位信息数据
listDwinfoGetList2.clear();
getThePageList(theHyshlx: 'dwxx').then((value) {
listDwinfoGetList2 = value;
print('listDwinfoGetList2 = \n$listDwinfoGetList2');
});
//监听违章信息数据更新事件
eventBus.on<LedXsxxUpdateEvent>().listen((event) async {
iPage = 0;
print(event.str);
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
_listSort();
});
//监听违章信息数据审核事件
eventBus.on<WzxxDataAuditEvent>().listen((event) async {
print('LedXsxxGetList: ' + event.str);
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
_listSort();
});
//监听违章信息Listview滚动事件
eventBus.on<WzxxDataScrollEvent>().listen((event) async {
firstIndex = event.firstIndex;
lastIndex = event.lastIndex;
try_setState();
});
super.initState();
}
//Led数据变量
// Map mapGetLedXsxxGetData = {
// "id": 2,
// "xsnr": "绿水青山就是金山银山 宜宾市生态环境局宣。",
// "addtime": "2021-01-20 10:16:07",
// "updatetime": "2021-02-13 11:48:51"
// };
Widget _getListTile(BuildContext context, indexRecord) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: Text(
"${(indexRecord + 1).toString()}. " +
listLedXsxxGetList2[indexRecord]['addtime'] +
' 添加',
style: TextStyle(fontSize: 10)),
subtitle: Text(getDate(listLedXsxxGetList2[indexRecord]['updatetime']) + ' 更新',
style: TextStyle(fontSize: 10)),
trailing: Container(
width: 180,
child: Text(
'id:' +
listLedXsxxGetList2[indexRecord]['id'].toString() +
', 显示信息:' +
listLedXsxxGetList2[indexRecord]['xsnr'],
maxLines: 2,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 12),
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
int ret = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => LedXsxxContent(
title: 'LED显示信息详情',
sbgllx: widget.sbgllx,
id: listLedXsxxGetList2[indexRecord]['id'],
),
),
);
print('ret = $ret');
},
),
Divider(height: 1.0),
],
);
}
ScrollController _controller = ScrollController(); //ListView控制器
bool isLoading = false; //正在处理下载数据、跳转到首项、跳转到尾项等操作
int firstIndex = 0; //ListView当前显示页面首项0基序号
int lastIndex = 0; //ListView当前显示页面末项0基序号
int itemOnPage = 8; //估计一屏显示的项目数量
Widget getIconButton({IconData iconData, var onPressed, double iconSize = 22}) {
return SizedBox(
height: iconSize,
width: iconSize + 10,
child: IconButton(
padding: EdgeInsets.all(0.0),
icon: Icon(iconData, size: iconSize),
onPressed: onPressed,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
//leading: Text(''),
titleSpacing: 0.0,
//设置title的左边距
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconData: Icons.arrow_back,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("${mapHyshlx[hyshlx]['text']}",
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: widget.sbgllx == 'fhycx' ? TextStyle(fontSize: 16) : null),
),
SizedBox(width: 5),
],
),
),
actions: <Widget>[
getDropdownButton(),
SizedBox(width: 10),
getIconButton(
iconData: Icons.cloud_download,
onPressed: !isLoading
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//print("I Pressed the Iconbutton");
int oldItems = listLedXsxxGetList2.length;
for (int i = 0; i < 10; i++) {
List list = await getPageList();
if (list.length > 0) {
listLedXsxxGetList2.addAll(list); //加载累加
} else {
break;
}
}
Future.delayed(const Duration(milliseconds: 1000), () async {
if (listLedXsxxGetList2.length > oldItems) {
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
Fluttertoast.showToast(
msg: '新增 ${listLedXsxxGetList2.length - oldItems} 条数据下载完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
_listSort();
}
isLoading = false;
try_setState();
});
}
: null,
),
getIconButton(
iconData: Icons.vertical_align_top_outlined,
onPressed: (!isLoading && (firstIndex > 0)) //未到顶部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.minScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到开头记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
firstIndex = 0;
lastIndex = itemOnPage - 1; //0基序号,所以需要减1
isLoading = false;
try_setState();
},
);
}
: null,
),
getIconButton(
iconData: Icons.vertical_align_bottom_outlined,
onPressed: (!isLoading && (lastIndex < listLedXsxxGetList2.length)) //未到尾部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.maxScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到末尾记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
//0基序号需要减1,再加上底部有一组显示信息,所以需要减2
firstIndex = listLedXsxxGetList2.length - itemOnPage - 2;
lastIndex = listLedXsxxGetList2.length;
isLoading = false;
try_setState();
},
);
}
: null,
),
],
),
body: (0 == listLedXsxxGetList2.length)
? getMoreWidget(color: Colors.black38)
: EasyRefresh(
child: ListView.custom(
controller: _controller,
cacheExtent: 1.0, // 只有设置了1.0 才能够准确的标记position 位置
childrenDelegate: MyChildrenDelegate(
_getListTile,
childCount: listLedXsxxGetList2.length,
),
),
onRefresh: () async {
// await Future.delayed(const Duration(seconds: 1), () async {
// iPage = 0;
// //await getWzxxGetList();
// listLedXsxxGetList2 = await getPageList();
// eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
// });
},
onLoad: () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
print('iPage = $iPage');
await Future.delayed(const Duration(seconds: 1), () async {
//await getWzxxGetList();
List list = await getPageList();
if (list.length > 0) {
listLedXsxxGetList2.addAll(list); //加载累加
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
}
isLoading = false;
try_setState();
});
},
header: getHeader(),
footer: getFooter(),
),
);
}
//DropdownButton需要设置初始值的时候,初始值必须是显示列表里面的值,否则会导致弹出框异常。
// 比如说:你的DropdownButton的items属性使用的是list这个列表里面的值,那么你的初始值应该在list[index]里面取,要不就会报错。
//
// There should be exactly one item with [DropdownButton]'s value: 0.0.
// Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
// 'package:flutter/src/material/dropdown.dart':
// Failed assertion: line 834 pos 15: 'items == null || items.isEmpty || value == null ||
// items.where((DropdownMenuItem<T> item) {
// return item.value == value;
// }).length == 1'
String _selectedValue = '主键ID';
bool _descending = false; //默认生效排列
Widget _getImage(String _image) {
return Container(
margin: EdgeInsets.only(),
height: ScreenUtil().setWidth(38),
width: ScreenUtil().setWidth(38),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(_image,
fit: BoxFit.cover, color: isLoading ? Theme.of(context).disabledColor : null));
}
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
Future _listSort({bool bShowToast = false}) {
if (!isLoading && listLedXsxxGetList2.length > 0) {
isLoading = true;
try_setState();
switch (_selectedValue) {
default:
if (_descending) {
//按_selectedValue排序,降序
listLedXsxxGetList2.sort((a, b) =>
(b[mapWzxxDataText[_selectedValue]]).compareTo(a[mapWzxxDataText[_selectedValue]]));
} else {
//按_selectedValue排序,升序
listLedXsxxGetList2.sort((a, b) =>
(a[mapWzxxDataText[_selectedValue]]).compareTo(b[mapWzxxDataText[_selectedValue]]));
}
break;
}
Future.delayed(const Duration(milliseconds: 1000), () {
if (bShowToast) {
Fluttertoast.showToast(
msg: '按“${_selectedValue}”${_descending ? '降序' : '升序'}排列完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
isLoading = false;
try_setState(); //避免如下异常报错
});
}
}
Widget getDropdownButtonItemText(String item) {
return Row(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment(0, 0.28),
child: item == _selectedValue
? _descending
? _getImage('assets/images/descending.png')
: _getImage('assets/images/ascending.png')
// ? Icon(Icons.arrow_downward_outlined, size: 20)
// : Icon(Icons.arrow_upward_outlined, size: 20)
: SizedBox(),
),
SizedBox(
width: 3,
),
Container(
//alignment: Alignment(0, -1),
child: Text(item,
style: isLoading
? TextStyle(color: Theme.of(context).disabledColor)
: (item == _selectedValue ? TextStyle(color: Colors.blue) : null)),
),
],
);
}
Widget getDropdownButton() {
//DropdownMenuItem项目文本list
List<String> itemList = [
'主键ID',
'添加时间',
'更新时间',
'显示信息',
];
//添加按'推送状态'排序
if (hyshlx != 'led_xsxx') {
itemList.removeLast();
itemList.addAll(['推送状态', '主键ID']);
}
//获取DropdownMenuItem项目组件list
List<DropdownMenuItem<String>> _dropDownMenuItems =
itemList.map<DropdownMenuItem<String>>((String item) {
return DropdownMenuItem<String>(
value: item,
child: getDropdownButtonItemText(item),
);
}).toList();
return Padding(
padding: EdgeInsets.only(top: 10, bottom: 10),
child: Container(
alignment: Alignment(0.7, 0),
width: 125,
margin: EdgeInsets.only(bottom: 0),
padding: EdgeInsets.only(left: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(width: 0),
//边框圆角设置
borderRadius:
BorderRadius.vertical(top: Radius.elliptical(2, 2), bottom: Radius.elliptical(2, 2)),
),
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
isDense: true,
value: _selectedValue,
items: _dropDownMenuItems,
onChanged: (String selectedValue) {
if (isLoading) {
return;
}
if (_selectedValue == selectedValue) {
_descending = !_descending;
} else {
_descending = true;
}
_selectedValue = selectedValue;
print('_selectedValue = $_selectedValue');
//按照用户选择的_selectedValue、_descending对listLedXsxxGetList2进行排序,并延时更新
_listSort(bShowToast: true);
},
),
),
),
);
}
}
//https://blog.csdn.net/u014803467/article/details/103750018
//Flutter 使用SliverChildBuilderDelegate获取ListView的第一个和最后一个可见Item序号
// 秋名山交警X 2019-12-28 23:52:52
class _SaltedValueKey extends ValueKey<Key> {
const _SaltedValueKey(Key key)
: assert(key != null),
super(key);
}
class MyChildrenDelegate extends SliverChildBuilderDelegate {
MyChildrenDelegate(
Widget Function(BuildContext, int) builder, {
int childCount,
bool addAutomaticKeepAlive = true,
bool addRepaintBoundaries = true,
}) : super(builder,
childCount: childCount,
addAutomaticKeepAlives: addAutomaticKeepAlive,
addRepaintBoundaries: addRepaintBoundaries);
// Return a Widget for the given Exception
Widget _createErrorWidget(dynamic exception, StackTrace stackTrace) {
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stackTrace,
library: 'widgets library',
context: ErrorDescription('building'),
);
FlutterError.reportError(details);
return ErrorWidget.builder(details);
}
@override
Widget build(BuildContext context, int index) {
assert(builder != null);
if (index < 0 || (childCount != null && index >= childCount)) return null;
Widget child;
try {
child = builder(context, index);
} catch (exception, stackTrace) {
child = _createErrorWidget(exception, stackTrace);
}
if (child == null) return null;
final Key key = child.key != null ? _SaltedValueKey(child.key) : null;
if (addRepaintBoundaries) child = RepaintBoundary(child: child);
if (addSemanticIndexes) {
final int semanticIndex = semanticIndexCallback(child, index);
if (semanticIndex != null)
child = IndexedSemantics(index: semanticIndex + semanticIndexOffset, child: child);
}
if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child);
return KeyedSubtree(child: child, key: key);
}
@override
void didFinishLayout(int _firstIndex, int _lastIndex) {
// TODO: implement didFinishLayout
super.didFinishLayout(_firstIndex, _lastIndex);
}
///监听 在可见的列表中 显示的第一个位置和最后一个位置
@override
double estimateMaxScrollOffset(
int _firstIndex, int _lastIndex, double _leadingScrollOffset, double _trailingScrollOffset) {
//违章信息Listview滚动广播
eventBus.fire(WzxxDataScrollEvent(_firstIndex, _lastIndex));
return super.estimateMaxScrollOffset(
_firstIndex, _lastIndex, _leadingScrollOffset, _trailingScrollOffset);
}
}
+595
View File
@@ -0,0 +1,595 @@
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/customDialogF.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/customRadioWidget.dart';
import '../../../components/doJSON.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import 'dart:io';
import '../../../components/customDialogH.dart';
import '../../../components/customDialogJ.dart';
class SbbjContent extends StatefulWidget {
//SbbjContent({Key key, this.title, this.mapData}) : super(key: key);
SbbjContent({
@required this.title,
@required this.index,
@required this.hyshlx,
Key key,
}) : super(key: key);
String title;
int index = -1;
String hyshlx;
_SbbjPageState createState() => _SbbjPageState();
}
class _SbbjPageState extends State<SbbjContent> {
Map _mapGetSbbjGetDataText = {
"id": "主键ID",
"bjlx": "设备类型",
"content": "报警内容",
"dwip": "点位IP",
"sbip": "设备IP",
"addtime": "添加时间",
"workflow": "处理状态"
};
Map _mapGetSbbjGetData = {
"id": 1177,
"bjlx": "风扇",
"content": "串口COM1获取风扇异常数据",
"dwip": "172.16.3.1",
"sbip": "192.168.1.10",
"addtime": "2021-02-07 23:56:45",
"workflow": 999
};
List<TextEditingController> _listController = [];
int listLen = 0;
String nums = '';
int _selectedRadio = 0;
void initState() {
// TODO: implement initState
super.initState();
listLen = listSbbjGetList2.length;
getListFlields();
}
//监听登录页面销毁的事件
dispose() {
_controller.dispose();
super.dispose();
}
getListFlields() async {
//获取指定id的sbbj记录数据返回 _mapGetSbbjGetData。由于 sbbj 信息需要进行查核处理,所以要重新读取最新的记录数据
_mapGetSbbjGetData =
await getLedXsxxGetData(id: listSbbjGetList2[widget.index]['id'], theSbgllx: widget.hyshlx);
print('_mapGetSbbjGetData = ${_mapGetSbbjGetData}');
//_mapGetSbbjGetData = listSbbjGetList2[widget.index];
_listController = List.generate(_mapGetSbbjGetData.length, (index) {
String key = _mapGetSbbjGetData.keys.elementAt(index);
String strContent = _mapGetSbbjGetData[key].toString();
//时间戳转换
if (strContent.isNotEmpty && 'addtime' == key) {
strContent = getDate(strContent);
}
//workflow转换
if (strContent.isNotEmpty && 'workflow' == key) {
strContent = strContent == '999' ? '已处理' : '待处理';
}
var controller = TextEditingController(text: strContent);
controller.selection = TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: '${controller.text}'.length),
);
return controller;
});
getPreBtn_NextBtn();
nums = '${(widget.index + 1).toString()} / $listLen';
setState(() {});
}
Widget getTrail(String key, int index, double widthTrail) {
if (0 == _listController.length) {
return Container(width: widthTrail);
}
//print('key = $key');
if ('avatar' == key) {
imagePath = _listController[index].text;
return getAvatar(width: widthTrail);
} else {
return Container(
alignment: Alignment(-1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
//解决信息显示不全问题
child: Text(_listController[index].text,
style: TextStyle(fontSize: 16), textAlign: TextAlign.left),
);
}
}
Widget getTrail0(String key, int index, double widthTrail) {
if (0 == _listController.length) {
return Container(width: widthTrail);
}
//print('key = $key');
if ('avatar' == key) {
imagePath = _listController[index].text;
return getAvatar(width: widthTrail);
} else {
return Container(
alignment: Alignment(1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
child: TextField(
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
decoration: InputDecoration(
//hintText: '請輸入字段信息',
border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
),
controller: _listController[index],
enabled: 'content' == key ? true : false,
//解决报警信息显示不全问题,但软键盘会弹出,很难控制键盘弹出问题
//利用控制器初始化文本
onChanged: null,
),
);
}
}
Future<String> doContacts() async {
bFlash = false;
return showDialog(
context: context,
builder: (BuildContext context) {
return customDialogH(
title: "请选择头像修改操作",
content: "头像修改",
index: 0,
);
},
).then((value) {
imagePath = value;
print('Page2_Contacts bFlash = $bFlash');
if (imagePath.isNotEmpty) {
_image = Image.file(File(imagePath), fit: BoxFit.cover);
setState(() {});
}
});
}
//Image.file(this._image);
String imagePath = '';
Image _image;
Widget getAvatar({double width = 260.0}) {
if (imagePath.isEmpty) {
_image = Image.asset('assets/images/user.png', fit: BoxFit.cover);
} else {
String head = imagePath.substring(0, 4).trim().toLowerCase();
if ('http' == head) {
_image = Image.network(imagePath, fit: BoxFit.cover);
}
}
return Container(
alignment: Alignment(-1, 0),
width: width,
child: InkWell(
onTap: () async {
doContacts();
},
child: Container(
width: 40,
child: _image,
),
),
);
}
//添加、修改、删除联系人对话框
doContacts2(String key, int index) async {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialogJ(
theKey: key,
index: index,
);
},
);
}
static onNullFun() {}
Widget _getListTile(String key, int index, double widthTrail,
{onTapFun = onNullFun, onLongPressFun = onNullFun, size = 16.0}) {
//print('key = $key, index = $index');
return ListTile(
//leading: new Icon(Icons.phone),
title: Text((index + 1).toString() + ". " + '${_mapGetSbbjGetDataText[key]} :',
style: TextStyle(fontSize: 16)),
trailing: getTrail(key, index, widthTrail),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
// print('第 $index 项被点击了');
// await doContacts2(key, index);
// if ('avatar' == key) {
// print('选择图片或拍照');
// await doContacts();
// }
},
onLongPress: () {},
);
}
TextEditingController _controller = TextEditingController.fromValue(TextEditingValue(
text: '已做简单处理。低级故障,不影响系统运行',
// 保持光标在最后
selection: TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: '已处理'.length))));
//7、得到核查处理意见组件
Widget getClyj(int index, bool _bCheck) {
if (_bCheck) {
_controller.text = '';
} else {
_controller.text = (0 == _selectedRadio ? '已做简单处理。低级故障,不影响系统运行' : '已核查,属于误报');
}
return ConstrainedBox(
constraints: BoxConstraints(
minWidth: double.infinity, //宽度尽可能大
//minHeight: _listTileHeight, //最小高度
maxHeight: _heigth, //最大高度
),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.baseline,
children: <Widget>[
SizedBox(width: _marginLeft),
Text('处理意见:',
style: TextStyle(
fontSize: _fontSize,
color: _bCheck
? Colors.grey
: 0 == _selectedRadio
? Colors.red
: Colors.green)),
Container(
alignment: Alignment(-1, 0),
height: _heigth,
//widthTrail = 400报错,360刚能显示,300换行,260
width: 240,
child: TextField(
//textAlign: TextAlign.right,
//style: TextStyle(fontSize: _fontSize, color: cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])].cpysFont),
//style: TextStyle(fontSize: _fontSize, color: cpysList[getIndexOfCpysList(colorText: myCpys)].cpysFont),
style: TextStyle(fontSize: _fontSize),
textAlign: TextAlign.left,
decoration: InputDecoration(
hintText: _bCheck ? '' : '請輸入审核意见',
//border: InputBorder.none, //TextField去掉下划线
//contentPadding: EdgeInsets.only(right: 0),
//contentPadding: EdgeInsets.symmetric(vertical: _textFieldHeight),
contentPadding: EdgeInsets.only(left: 4, right: 4), //这行代码是关键,设置这个之后,居中
//contentPadding: EdgeInsets.zero, //这行代码是关键,设置这个之后,居中
border: OutlineInputBorder(
borderSide: BorderSide(color: Colors.grey[600]),
//borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(3),
),
),
controller: _controller,
maxLines: 1,
minLines: 1,
//maxLengthEnforced: false,
//maxLength: 10,
enabled: !_bCheck,
//利用控制器初始化文本
onChanged: (value) {
_controller.text = value;
},
),
),
],
),
);
}
double _heigth = 30;
double _fontSize = 16;
double _marginLeft = 15;
@override
Widget build(BuildContext context) {
bool bCheck = _mapGetSbbjGetData['workflow'] == 999; //已处理
return Scaffold(
// appBar: AppBar(
// title: Text("设备报警信息详情($nums)"),
// centerTitle: true,
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text("设备报警信息详情($nums)",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
//https://www.it1352.com/2028416.html
//用Map而不是List的Flutter ListView.builder(Flutter listview with Map instead of List)
//使用ListView.separated设置分割线ListView.separated(
//child: ListView.separated( //这种方式不能设置每项高度,每页只能有7项
child: ListView.builder(
//这种方式可以通过itemExtent设置每项高度,每页可以有9项
//separatorBuilder: (BuildContext context, int index) => index %2 ==0? Divider(color: Colors.green) : Divider(color: Colors.red),//index为偶数,创建绿色分割线;index为奇数,则创建红色分割线
//separatorBuilder: (BuildContext context, int index) => Divider(),
//itemExtent: 57.0, //列表项高度。56越界、57刚好。还是自动计算最好
itemCount: _mapGetSbbjGetData.length,
itemBuilder: (BuildContext context, index) {
String key = _mapGetSbbjGetData.keys.elementAt(index);
return Column(
children: <Widget>[
_getListTile(key, index, 200.0),
Divider(
height: 1.0,
),
],
);
},
),
),
//7、得到核查处理意见组件
Divider(height: 1.0, color: Colors.blue),
SizedBox(height: 15),
getClyj(widget.index, bCheck),
SizedBox(height: 10),
//8、处理结果
Container(
height: _heigth,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: _marginLeft),
Text('处理结果:',
style: TextStyle(
fontSize: _fontSize,
color: bCheck
? Colors.grey
: 0 == _selectedRadio
? Colors.red
: Colors.green)),
CustomRadioWidget(
value: 0,
title: "已处理",
fontSize: _fontSize,
width: 120,
groupValue: _selectedRadio,
onChanged: bCheck
? null
: (int value) {
_selectedRadio = value;
//黑烟初审数据审核Radio选项改变广播
//eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
_controller.text = '已做简单处理。低级故障,不影响系统运行';
setState(() {});
print('selectedRadio = ${_selectedRadio.toString()}');
},
),
SizedBox(width: 20),
CustomRadioWidget(
value: 1,
title: "误报",
fontSize: _fontSize,
width: 100,
groupValue: _selectedRadio,
onChanged: bCheck
? null
: (int value) {
_selectedRadio = value;
//黑烟初审数据审核Radio选项改变广播
//eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
_controller.text = '已核查,属于误报';
setState(() {});
print('selectedRadio = ${_selectedRadio.toString()}');
},
),
],
),
),
SizedBox(height: 10),
Divider(height: 1.0, color: Colors.blue),
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(
text: "处理",
onPressedFun: bCheck
? null
: () async {
int ret = -1;
print('等待处理确认');
await Navigator.of(context)
.push(
PageRouteBuilder(
opaque: false,
pageBuilder: (context, animation, secondaryAnimation) =>
CustomDialogF(title: '处理确认', content: '是否进行设备报警信息核查处理?'),
),
)
.then((value) async {
print('value = $value');
if (value) {
print('用户已确认,开始处理报警信息核查处理!');
// sbglContentFirstAudit 整型返回值:更新的结果,1表示成功,0表示无更新,false表示失败
ret = await sbglContentAudit(
sbgllx: widget.hyshlx,
sbglID: _mapGetSbbjGetData['id'],
shuoming: _controller.text,
title: 0 == _selectedRadio ? '已处理' : '误报',
);
if (1 == ret) {
eventBus.fire(SbglDataUpdateEvent(
'${mapHyshlx[widget.hyshlx]['text']}数据已更新'));
print('${mapHyshlx[widget.hyshlx]['text']}结果已成功上传服务器。');
}
} else {
print('用户取消了报警信息核查处理');
}
});
Navigator.pop(context, ret);
}),
//getBtnSizeX(text: "删除", onPressedFun: () async {}),
preBtn,
nextBtn,
],
),
SizedBox(height: 20),
],
),
),
);
}
//解决第一次进入报错问题。因为getPreBtn_NextBtn()还未执行,preBtn和nextBtn为空
Widget preBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('上一条'),
onPressed: null,
),
);
Widget nextBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('下一条'),
onPressed: null,
),
);
getPreBtn_NextBtn() {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: null,
);
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: null,
);
if (widget.index > 0 && listLen > 0) {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: () async {
if (widget.index > 0) {
widget.index--;
getListFlields();
}
},
);
}
if (widget.index < (listLen - 1) && listLen > 0) {
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: () async {
if (widget.index < listLen - 1) {
widget.index++;
getListFlields();
}
},
);
}
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
+799
View File
@@ -0,0 +1,799 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'sbbj_content.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../components/commonFun.dart';
import '../../../services/EventBus.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import '../../../components/doJSON.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//sbbj是本项目中“设备报警”的统一缩写
class SbbjGetList extends StatefulWidget {
//hyshlx为黑烟审核类型,处理sbbj信息。mapHyshlx[hyshlx]获取为各种类型的设置数据
SbbjGetList({this.hyshlx = 'sbbj', Key key}) : super(key: key);
String hyshlx;
_SbbjPageState createState() => _SbbjPageState();
}
class _SbbjPageState extends State<SbbjGetList> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void dispose() {
_controller.dispose(); //销毁控制器
super.dispose();
}
@override
void initState() {
hyshlx = widget.hyshlx;
iPage = 0;
listSbbjGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList().then((value) {
listSbbjGetList2 = value;
//按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
});
///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据,返回 list
///获取点位信息数据
listDwinfoGetList2.clear();
getThePageList(theHyshlx: 'dwxx').then((value) {
listDwinfoGetList2 = value;
print('listDwinfoGetList2 = \n$listDwinfoGetList2');
});
//监听设备管理信息数据更新事件
eventBus.on<SbglDataUpdateEvent>().listen((event) async {
print(event.str);
iPage = 0;
listSbbjGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList().then((value) {
listSbbjGetList2 = value;
//按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
});
});
super.initState();
}
// List listSbbjGetList2 = [
// {
// "id": 1196,
// "bjlx": "风扇",
// "content": "串口COM1获取风扇异常数据",
// "dwip": "172.16.3.12",
// "sbip": "192.168.1.10",
// "addtime": "2021-02-16 09:50:30",
// "workflow": 999
// },
// ];
Widget _getListTile(BuildContext context, indexRecord) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: Text(
"${(indexRecord + 1).toString()}. " +
getDate(listSbbjGetList2[indexRecord]['addtime']) +
',',
style: TextStyle(fontSize: 14)),
subtitle: Text(
getDwmc(listSbbjGetList2[indexRecord]['dwip']) +
',' +
(listSbbjGetList2[indexRecord]['workflow'] == 999 ? '已处理' : '待处理'),
style: TextStyle(fontSize: 14)),
trailing: Container(
width: 160,
child: Text(
'${listSbbjGetList2[indexRecord]['bjlx']}, 报警:${listSbbjGetList2[indexRecord]['content']}' +
', 设备IP:${listSbbjGetList2[indexRecord]['sbip']}' +
'ID:${listSbbjGetList2[indexRecord]['id'].toString()}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 14),
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
int ret = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => SbbjContent(
title: '设备报警信息',
index: indexRecord,
hyshlx: widget.hyshlx,
),
),
);
print('ret = $ret');
},
),
Divider(height: 1.0),
],
);
}
ScrollController _controller = ScrollController(); //ListView控制器
bool isLoading = false; //正在处理下载数据、跳转到首项、跳转到尾项等操作
int firstIndex = 0; //ListView当前显示页面首项0基序号
int lastIndex = 0; //ListView当前显示页面末项0基序号
int itemOnPage = 8; //估计一屏显示的项目数量
Widget getIconButton({IconData iconData, var onPressed, double iconSize = 22}) {
return SizedBox(
height: iconSize,
width: iconSize + 10,
child: IconButton(
padding: EdgeInsets.all(0.0),
icon: Icon(iconData, size: iconSize, color: Colors.white),
onPressed: onPressed,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// automaticallyImplyLeading: false,
// centerTitle: true,
// //leading: Text(''),
// titleSpacing: 0.0,
// //设置title的左边距
// title: Padding(
// padding: EdgeInsets.only(left: 0, right: 0),
// child: Row(
// //mainAxisAlignment: MainAxisAlignment.start,
// children: [
// getIconAndTextButton(
// iconData: Icons.arrow_back,
// onPress: () {
// Navigator.pop(context);
// },
// ),
// Expanded(
// child: Text("${mapHyshlx[hyshlx]['text']}",
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// style: widget.hyshlx == 'fhycx' ? TextStyle(fontSize: 14) : null),
// ),
// SizedBox(width: 5),
// ],
// ),
// ),
// actions: <Widget>[
// getDropdownButton(),
// SizedBox(width: 10),
// getIconButton(
// iconData: Icons.cloud_download,
// onPressed: !isLoading
// ? () async {
// if (isLoading) {
// return;
// }
// isLoading = true;
// try_setState();
// //print("I Pressed the Iconbutton");
// int oldItems = listSbbjGetList2.length;
// for (int i = 0; i < 10; i++) {
// List list = await getPageList();
// if (list.length > 0) {
// listSbbjGetList2.addAll(list); //加载累加
// } else {
// break;
// }
// }
// Future.delayed(const Duration(milliseconds: 1000), () async {
// if (listSbbjGetList2.length > oldItems) {
// eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
// Fluttertoast.showToast(
// msg: '新增 ${listSbbjGetList2.length - oldItems} 条数据下载完成!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
//
// //按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
// _listSort();
// }
// isLoading = false;
// try_setState();
// });
// }
// : null,
// ),
// getIconButton(
// iconData: Icons.vertical_align_top_outlined,
// onPressed: (!isLoading && (firstIndex > 0)) //未到顶部
// ? () async {
// if (isLoading) {
// return;
// }
// isLoading = true;
// try_setState();
//
// //必须延时执行,否则不能及时完成按钮状态更新
// Timer(
// Duration(milliseconds: 500),
// () {
// _controller.jumpTo(_controller.position.minScrollExtent);
// },
// );
//
// Timer(
// Duration(milliseconds: 1000),
// () {
// // Fluttertoast.showToast(
// // msg: '已经跳转到开头记录!',
// // toastLength: Toast.LENGTH_SHORT,
// // gravity: ToastGravity.CENTER,
// // );
// firstIndex = 0;
// lastIndex = itemOnPage - 1; //0基序号,所以需要减1
// isLoading = false;
// try_setState();
// },
// );
// }
// : null,
// ),
// getIconButton(
// iconData: Icons.vertical_align_bottom_outlined,
// onPressed: (!isLoading && (lastIndex < listSbbjGetList2.length)) //未到尾部
// ? () async {
// if (isLoading) {
// return;
// }
// isLoading = true;
// try_setState();
//
// //必须延时执行,否则不能及时完成按钮状态更新
// Timer(
// Duration(milliseconds: 500),
// () {
// _controller.jumpTo(_controller.position.maxScrollExtent);
// },
// );
//
// Timer(
// Duration(milliseconds: 1000),
// () {
// // Fluttertoast.showToast(
// // msg: '已经跳转到末尾记录!',
// // toastLength: Toast.LENGTH_SHORT,
// // gravity: ToastGravity.CENTER,
// // );
// //0基序号需要减1,再加上底部有一组显示信息,所以需要减2
// firstIndex = listSbbjGetList2.length - itemOnPage - 2;
// lastIndex = listSbbjGetList2.length;
// isLoading = false;
// try_setState();
// },
// );
// }
// : null,
// ),
// ],
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // here the desired height
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
//leading: Text(''),
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
//1、第1行组件,工具按钮
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
//1.1、返回按钮
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
//1.2、title 显示控制
Expanded(
child: Text("${mapHyshlx[hyshlx]['text']}",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.white, fontSize: 20)),
),
SizedBox(width: 5),
],
),
),
//1.3、尾部工具按钮组
actions: <Widget>[
//getDropdownButton(),
getIconButton(
iconData: Icons.cloud_download,
onPressed: !isLoading
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//print("I Pressed the Iconbutton");
int oldItems = listSbbjGetList2.length;
for (int i = 0; i < 10; i++) {
List list = await getPageList();
if (list.length > 0) {
listSbbjGetList2.addAll(list); //加载累加
} else {
break;
}
}
Future.delayed(const Duration(milliseconds: 1000), () async {
if (listSbbjGetList2.length > oldItems) {
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
Fluttertoast.showToast(
msg: '新增 ${listSbbjGetList2.length - oldItems} 条数据下载完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
//按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
_listSort();
//_controller.jumpTo(1); // _controller.position 能够有效刷新,人眼可察觉的滚动
_controller.jumpTo(0.001); // _controller.position 完美解决有效刷新,而且人眼不可见察觉滚动
//第二次跳转必须延时,否则 _controller.position 不能有效刷新
Future.delayed(Duration(milliseconds: 500), () {
_controller.jumpTo(_controller.position.minScrollExtent);
});
}
isLoading = false;
try_setState();
});
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
getIconButton(
iconData: Icons.vertical_align_top_outlined,
onPressed: (!isLoading && (firstIndex > 0)) //未到顶部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.minScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到开头记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
firstIndex = 0;
lastIndex = itemOnPage - 1; //0基序号,所以需要减1
isLoading = false;
try_setState();
},
);
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
getIconButton(
iconData: Icons.vertical_align_bottom_outlined,
onPressed: (!isLoading && (lastIndex < listSbbjGetList2.length)) //未到尾部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.maxScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到末尾记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
//0基序号需要减1,再加上底部有一组显示信息,所以需要减2
firstIndex = listSbbjGetList2.length - itemOnPage - 2;
lastIndex = listSbbjGetList2.length;
isLoading = false;
try_setState();
},
);
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
],
),
),
body: Column(children: [
//2、第2行排序按钮
Container(
height: ScreenUtil().setHeight(142),
decoration: new BoxDecoration(border: new Border.all(color: Colors.red)),
child: Row(
children: [
SizedBox(width: ScreenUtil().setWidth(50)),
Text('排序', style: TextStyle(fontSize: 18)),
Expanded(child: SizedBox.shrink()),
getDropdownButton(),
SizedBox(width: ScreenUtil().setWidth(20)),
],
),
),
(0 == listSbbjGetList2.length)
? getMoreWidget(color: Colors.black38)
: Expanded(
child: EasyRefresh(
child: ListView.custom(
//itemExtent: 75.0, //列表项高度
controller: _controller,
cacheExtent: 1.0, // 只有设置了1.0 才能够准确的标记 position 位置
childrenDelegate: MyChildrenDelegate(
_getListTile,
childCount: listSbbjGetList2.length,
),
),
onRefresh: () async {
// await Future.delayed(const Duration(seconds: 1), () async {
// iPage = 0;
// //await getWzxxGetList();
// listSbbjGetList2 = await getPageList();
// eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
// });
},
onLoad: () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
print('iPage = $iPage');
await Future.delayed(const Duration(seconds: 1), () async {
//await getWzxxGetList();
List list = await getPageList();
if (list.length > 0) {
listSbbjGetList2.addAll(list); //加载累加
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
}
isLoading = false;
try_setState();
});
},
header: getHeader(),
footer: getFooter(),
),
),
]),
);
}
//DropdownButton需要设置初始值的时候,初始值必须是显示列表里面的值,否则会导致弹出框异常。
// 比如说:你的DropdownButton的items属性使用的是list这个列表里面的值,那么你的初始值应该在list[index]里面取,要不就会报错。
//
// There should be exactly one item with [DropdownButton]'s value: 0.0.
// Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
// 'package:flutter/src/material/dropdown.dart':
// Failed assertion: line 834 pos 15: 'items == null || items.isEmpty || value == null ||
// items.where((DropdownMenuItem<T> item) {
// return item.value == value;
// }).length == 1'
String _selectedValue = '添加时间';
bool _descending = true; //默认生效排列
Widget _getImage(String _image) {
return Container(
margin: EdgeInsets.only(),
height: ScreenUtil().setWidth(48),
width: ScreenUtil().setWidth(48),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(_image,
fit: BoxFit.cover, color: isLoading ? Theme.of(context).disabledColor : null));
}
//按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
Future _listSort({bool bShowToast = false}) {
if (!isLoading && listSbbjGetList2.length > 0) {
isLoading = true;
try_setState();
switch (_selectedValue) {
default:
if (_descending) {
//按_selectedValue排序,降序
listSbbjGetList2.sort((a, b) =>
(b[mapWzxxDataText[_selectedValue]]).compareTo(a[mapWzxxDataText[_selectedValue]]));
} else {
//按_selectedValue排序,升序
listSbbjGetList2.sort((a, b) =>
(a[mapWzxxDataText[_selectedValue]]).compareTo(b[mapWzxxDataText[_selectedValue]]));
}
break;
}
Future.delayed(const Duration(milliseconds: 1000), () {
if (bShowToast) {
Fluttertoast.showToast(
msg: '按“${_selectedValue}”${_descending ? '降序' : '升序'}排列完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
isLoading = false;
try_setState(); //避免如下异常报错
});
}
}
Widget getDropdownButtonItemText(String item) {
return Padding(
padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(3)),
child: Row(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment(0, 0),
padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
child: item == _selectedValue
? _descending
? _getImage('assets/images/descending.png')
: _getImage('assets/images/ascending.png')
// ? Icon(Icons.arrow_downward_outlined, size: 20)
// : Icon(Icons.arrow_upward_outlined, size: 20)
: SizedBox(),
),
SizedBox(
width: ScreenUtil().setWidth(10),
),
Container(
//alignment: Alignment(0, -1),
child: Text(item,
style: TextStyle(
fontSize: 18,
color: isLoading
? Theme.of(context).disabledColor
: item == _selectedValue
? Colors.blue
: null)),
// style: isLoading
// ? TextStyle(color: Theme.of(context).disabledColor)
// : (item == _selectedValue ? TextStyle(color: Colors.blue) : null)),
),
],
),
);
}
// List listSbbjGetList2 = [
// {
// "id": 1196,
// "bjlx": "风扇",
// "content": "串口COM1获取风扇异常数据",
// "dwip": "172.16.3.12",
// "sbip": "192.168.1.10",
// "addtime": "2021-02-16 09:50:30",
// "workflow": 999
// },
// ];
Widget getDropdownButton() {
//DropdownMenuItem项目文本list
List<String> itemList = [
'添加时间',
'主键ID',
'设备类型',
'报警内容',
'点位IP',
'设备IP',
'处理状态',
];
//添加按'推送状态'排序
if (hyshlx != 'sbbj') {
// itemList.removeLast();
// itemList.addAll(['推送状态', '主键ID']);
}
//获取DropdownMenuItem项目组件list
List<DropdownMenuItem<String>> _dropDownMenuItems =
itemList.map<DropdownMenuItem<String>>((String item) {
return DropdownMenuItem<String>(
value: item,
child: getDropdownButtonItemText(item),
);
}).toList();
return Padding(
padding: EdgeInsets.only(top: 0, bottom: 0),
child: Container(
alignment: Alignment(0, 0),
width: 135,
margin: EdgeInsets.only(bottom: 0),
padding: EdgeInsets.only(left: 0, bottom: 0),
// decoration: BoxDecoration(
// border: Border.all(width: 0),
// //边框圆角设置
// borderRadius:
// BorderRadius.vertical(top: Radius.elliptical(2, 2), bottom: Radius.elliptical(2, 2)),
// ),
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
iconSize: ScreenUtil().setHeight(100),
//itemHeight: ScreenUtil().setHeight(372),
isDense: true,
value: _selectedValue,
items: _dropDownMenuItems,
onChanged: (String selectedValue) {
if (isLoading) {
return;
}
if (_selectedValue == selectedValue) {
_descending = !_descending;
} else {
_descending = true;
}
_selectedValue = selectedValue;
print('_selectedValue = $_selectedValue');
//按抓拍次数排序,降序
// listSbbjGetList2.sort((a, b) => (b["yjxx_id"].split(',').length.toString())
// .compareTo(a["yjxx_id"].split(',').length.toString()));
//按照用户选择的_selectedValue、_descending对listSbbjGetList2进行排序,并延时更新
_listSort();
},
),
),
),
);
}
}
//https://blog.csdn.net/u014803467/article/details/103750018
//Flutter 使用SliverChildBuilderDelegate获取ListView的第一个和最后一个可见Item序号
// 秋名山交警X 2019-12-28 23:52:52
class _SaltedValueKey extends ValueKey<Key> {
const _SaltedValueKey(Key key)
: assert(key != null),
super(key);
}
class MyChildrenDelegate extends SliverChildBuilderDelegate {
MyChildrenDelegate(
Widget Function(BuildContext, int) builder, {
int childCount,
bool addAutomaticKeepAlive = true,
bool addRepaintBoundaries = true,
}) : super(builder,
childCount: childCount,
addAutomaticKeepAlives: addAutomaticKeepAlive,
addRepaintBoundaries: addRepaintBoundaries);
// Return a Widget for the given Exception
Widget _createErrorWidget(dynamic exception, StackTrace stackTrace) {
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stackTrace,
library: 'widgets library',
context: ErrorDescription('building'),
);
FlutterError.reportError(details);
return ErrorWidget.builder(details);
}
@override
Widget build(BuildContext context, int index) {
assert(builder != null);
if (index < 0 || (childCount != null && index >= childCount)) return null;
Widget child;
try {
child = builder(context, index);
} catch (exception, stackTrace) {
child = _createErrorWidget(exception, stackTrace);
}
if (child == null) return null;
final Key key = child.key != null ? _SaltedValueKey(child.key) : null;
if (addRepaintBoundaries) child = RepaintBoundary(child: child);
if (addSemanticIndexes) {
final int semanticIndex = semanticIndexCallback(child, index);
if (semanticIndex != null)
child = IndexedSemantics(index: semanticIndex + semanticIndexOffset, child: child);
}
if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child);
return KeyedSubtree(child: child, key: key);
}
@override
void didFinishLayout(int _firstIndex, int _lastIndex) {
// TODO: implement didFinishLayout
super.didFinishLayout(_firstIndex, _lastIndex);
}
///监听 在可见的列表中 显示的第一个位置和最后一个位置
@override
double estimateMaxScrollOffset(
int _firstIndex, int _lastIndex, double _leadingScrollOffset, double _trailingScrollOffset) {
//违章信息Listview滚动广播
eventBus.fire(WzxxDataScrollEvent(_firstIndex, _lastIndex));
return super.estimateMaxScrollOffset(
_firstIndex, _lastIndex, _leadingScrollOffset, _trailingScrollOffset);
}
}
+476
View File
@@ -0,0 +1,476 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import '../../../components/customDialogH.dart';
import '../../../components/customDialogJ.dart';
import '../../../components/dioFun.dart';
//import 'package:hyzp_ybqx/widget/player_pro.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
class DwxxContent extends StatefulWidget {
//SbglContent({Key key, this.title, this.mapData}) : super(key: key);
DwxxContent({
@required this.title,
@required this.index,
@required this.hyshlx,
Key key,
}) : super(key: key);
String title;
int index = -1;
String hyshlx;
_SbglPageState createState() => _SbglPageState();
}
class _SbglPageState extends State<DwxxContent> {
Map _mapGetSbglGetDataText = {
"id": "主键ID",
"dwip": "点位IP",
"dwmc": '点位名称',
"dwbh": '点位编号',
"dwinfo": '点位信息',
"dwzb": '点位坐标',
"dwms": '点位描述',
"dwzt": '点位状态',
};
//点位信息数据
Map _mapGetSbglGetData = {
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "江北振兴大道",
"dwbh": 1,
"dwinfo": "江北振兴大道入城方向",
"dwzb": "104.607091|28.807061",
"dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆",
"dwzt": "正常"
};
List<TextEditingController> _listController = [];
int listLen = 0;
String nums = '';
int _selectedRadio = 0;
void initState() {
// TODO: implement initState
super.initState();
listLen = listSbglGetList2.length;
getListFlields();
}
//监听登录页面销毁的事件
dispose() {
_controller.dispose();
getingDwVideo = false;
super.dispose();
}
getListFlields() async {
//获取指定id的sbgl记录数据返回 _mapGetSbglGetData。由于 sbgl 信息需要进行查核处理,所以要重新读取最新的记录数据
// _mapGetSbglGetData =
// await getLedXsxxGetData(id: listSbglGetList2[widget.index]['id'], theSbgllx: widget.hyshlx);
_mapGetSbglGetData = listSbglGetList2[widget.index];
print('_mapGetSbglGetData = ${_mapGetSbglGetData}');
//_mapGetSbglGetData = listSbglGetList2[widget.index];
_listController = List.generate(_mapGetSbglGetData.length, (index) {
String key = _mapGetSbglGetData.keys.elementAt(index);
String strContent = _mapGetSbglGetData[key].toString();
//时间戳转换
if (strContent.isNotEmpty && 'addtime' == key) {
strContent = getDate(strContent);
}
//workflow转换
if (strContent.isNotEmpty && 'workflow' == key) {
strContent = strContent == '999' ? '已处理' : '待处理';
}
var controller = TextEditingController(text: strContent);
controller.selection = TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: '${controller.text}'.length),
);
return controller;
});
getPreBtn_NextBtn();
nums = '${(widget.index + 1).toString()} / $listLen';
setState(() {});
}
Widget getTrail(String key, int index, double widthTrail) {
if (0 == _listController.length) {
return Container(width: widthTrail);
}
//print('key = $key');
if ('avatar' == key) {
imagePath = _listController[index].text;
return getAvatar(width: widthTrail);
} else {
return Container(
alignment: Alignment(-1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
//解决信息显示不全问题
child: Text(_listController[index].text,
style: TextStyle(fontSize: 'dwms' == key ? 14 : 16), textAlign: TextAlign.left),
);
}
}
Widget getTrail0(String key, int index, double widthTrail) {
if (0 == _listController.length) {
return Container(width: widthTrail);
}
//print('key = $key');
if ('avatar' == key) {
imagePath = _listController[index].text;
return getAvatar(width: widthTrail);
} else {
return Container(
alignment: Alignment(1, 0),
//widthTrail = 400报错,360刚能显示,300换行,260
width: widthTrail,
child: TextField(
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 16),
decoration: InputDecoration(
//hintText: '請輸入字段信息',
border: InputBorder.none, //TextField去掉下划线
contentPadding: EdgeInsets.only(right: 0),
),
controller: _listController[index],
enabled: false,
//利用控制器初始化文本
onChanged: (value) {},
),
);
}
}
Future<String> doContacts() async {
bFlash = false;
return showDialog(
context: context,
builder: (BuildContext context) {
return customDialogH(
title: "请选择头像修改操作",
content: "头像修改",
index: 0,
);
},
).then((value) {
imagePath = value;
print('Page2_Contacts bFlash = $bFlash');
if (imagePath.isNotEmpty) {
_image = Image.file(File(imagePath), fit: BoxFit.cover);
setState(() {});
}
});
}
//Image.file(this._image);
String imagePath = '';
Image _image;
Widget getAvatar({double width = 260.0}) {
if (imagePath.isEmpty) {
_image = Image.asset('assets/images/user.png', fit: BoxFit.cover);
} else {
String head = imagePath.substring(0, 4).trim().toLowerCase();
if ('http' == head) {
_image = Image.network(imagePath, fit: BoxFit.cover);
}
}
return Container(
alignment: Alignment(-1, 0),
width: width,
child: InkWell(
onTap: () async {
doContacts();
},
child: Container(
width: 40,
child: _image,
),
),
);
}
//添加、修改、删除联系人对话框
doContacts2(String key, int index) async {
showDialog(
context: context,
builder: (BuildContext context) {
return CustomDialogJ(
theKey: key,
index: index,
);
},
);
}
static onNullFun() {}
Widget _getListTile(String key, int index, double widthTrail,
{onTapFun = onNullFun, onLongPressFun = onNullFun, size = 16.0}) {
//print('key = $key, index = $index');
return ListTile(
//leading: new Icon(Icons.phone),
title: Text((index + 1).toString() + ". " + '${_mapGetSbglGetDataText[key]} :',
style: TextStyle(fontSize: 16)),
trailing: getTrail(key, index, widthTrail),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
// print('第 $index 项被点击了');
// await doContacts2(key, index);
// if ('avatar' == key) {
// print('选择图片或拍照');
// await doContacts();
// }
},
onLongPress: () {},
);
}
TextEditingController _controller = TextEditingController.fromValue(TextEditingValue(
text: '已做简单处理。低级故障,不影响系统运行',
// 保持光标在最后
selection: TextSelection.fromPosition(
TextPosition(affinity: TextAffinity.downstream, offset: '已处理'.length))));
double _heigth = 30;
double _fontSize = 16;
double _marginLeft = 15;
@override
Widget build(BuildContext context) {
bool bCheck = _mapGetSbglGetData['workflow'] == 999; //已处理
return Scaffold(
// appBar: AppBar(
// title: Text("设备点位信息详情($nums)"),
// centerTitle: true,
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
getingDwVideo = false;
Navigator.pop(context);
},
),
Expanded(
child: Text("设备点位信息详情($nums)",
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
child: Column(
children: <Widget>[
Expanded(
//https://www.it1352.com/2028416.html
//用Map而不是List的Flutter ListView.builder(Flutter listview with Map instead of List)
//使用ListView.separated设置分割线ListView.separated(
//child: ListView.separated( //这种方式不能设置每项高度,每页只能有7项
child: ListView.builder(
//这种方式可以通过itemExtent设置每项高度,每页可以有9项
//separatorBuilder: (BuildContext context, int index) => index %2 ==0? Divider(color: Colors.green) : Divider(color: Colors.red),//index为偶数,创建绿色分割线;index为奇数,则创建红色分割线
//separatorBuilder: (BuildContext context, int index) => Divider(),
//itemExtent: 57.0, //列表项高度。56越界、57刚好。还是自动计算最好
itemCount: _mapGetSbglGetData.length,
itemBuilder: (BuildContext context, index) {
String key = _mapGetSbglGetData.keys.elementAt(index);
return Column(
children: <Widget>[
_getListTile(key, index, 200.0),
Divider(
height: 1.0,
),
],
);
},
),
),
//7、得到核查处理意见组件
Divider(height: 1.0, color: Colors.blue),
SizedBox(height: 15),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
// getBtnSizeX(
// text: "复制",
// onPressedFun: () {
// // Flutter 复制文本到剪贴板
// Clipboard.setData(
// ClipboardData(text: listSbglGetList2[widget.index].toString()));
// Fluttertoast.showToast(msg: '点位信息已复制到剪贴板', gravity: ToastGravity.CENTER);
// }),
//getBtnSizeX(text: "删除", onPressedFun: () async {}),
getBtnSizeX(
text: "视频",
onPressedFun: () {
//getDwspUrl(index: widget.index, context: context);
getDwspUrlNew(indexRecord: widget.index, context: context);
// getDwspUrl(index: widget.index + 1).then((url) {
// print('index = ${(widget.index + 1).toString()}, url = $url');
// urlnew = url;
//
// //获取视频地址失败
// if (!isVideoUrl(urlnew)) {
// return;
// }
//
// var ret = Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => PlayerPro(
// url: urlnew,
// title:
// '点位视频\n${(widget.index + 1)}、${listDwinfoGetList2[widget.index]['dwmc']}',
// //initVideoSize: Size(704.0, 576.0),
// )));
// print('ret = $ret');
// });
//getDwVideoUrl(index: widget.index);
//getData();
// Flutter 复制文本到剪贴板
// Clipboard.setData(
// ClipboardData(text: listSbglGetList2[widget.index].toString()));
// Fluttertoast.showToast(msg: '点位信息已复制到剪贴板', gravity: ToastGravity.CENTER);
}),
preBtn,
nextBtn,
],
),
SizedBox(height: 20),
],
),
),
);
}
//解决第一次进入报错问题。因为getPreBtn_NextBtn()还未执行,preBtn和nextBtn为空
Widget preBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('上一条'),
onPressed: null,
),
);
Widget nextBtn = Container(
color: Colors.white12, //onPressedFun为null时无效
width: 70.0,
height: 35.0,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text('下一条'),
onPressed: null,
),
);
getPreBtn_NextBtn() {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: null,
);
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: null,
);
if (widget.index > 0 && listLen > 0) {
preBtn = getBtnSizeX(
text: "上一条",
onPressedFun: () async {
if (widget.index > 0) {
widget.index--;
getListFlields();
}
},
);
}
if (widget.index < (listLen - 1) && listLen > 0) {
nextBtn = getBtnSizeX(
text: "下一条",
onPressedFun: () async {
if (widget.index < listLen - 1) {
widget.index++;
getListFlields();
}
},
);
}
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
+820
View File
@@ -0,0 +1,820 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'dwxx_content.dart';
import '../../../components/dioFun.dart';
import '../../../components/hyxx_data_handle.dart';
import '../../../components/commonFun.dart';
import '../../../services/EventBus.dart';
import 'package:flutter_easyrefresh/easy_refresh.dart';
import '../../../components/doJSON.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//sbgl是本项目中“设备管理”的统一缩写
class DwxxGetList extends StatefulWidget {
//hyshlx为黑烟审核类型,处理sbgl信息。mapHyshlx[hyshlx]获取为各种类型的设置数据
DwxxGetList({this.hyshlx = 'dwxx', Key key}) : super(key: key);
String hyshlx;
_SbglPageState createState() => _SbglPageState();
}
class _SbglPageState extends State<DwxxGetList> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void dispose() {
_controller.dispose(); //销毁控制器
super.dispose();
}
@override
void initState() {
hyshlx = widget.hyshlx;
iPage = 0;
listSbglGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList().then((value) {
listSbglGetList2 = value;
//按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
//为播放点位视频读取数据
print('listDwspGetList2 = ${listDwspGetList2}');
listDwspGetList2 = listSbglGetList2;
listDwinfoGetList2 = listSbglGetList2;
print('listDwspGetList2 = ${listDwspGetList2}');
});
// ///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据,返回 list
// ///获取点位信息数据
// listDwinfoGetList2.clear();
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// });
//监听设备管理信息数据更新事件
eventBus.on<SbglDataUpdateEvent>().listen((event) async {
print(event.str);
iPage = 0;
listSbglGetList2.clear();
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据,返回 list
getPageList().then((value) {
listSbglGetList2 = value;
//按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
_listSort();
firstIndex = 0;
lastIndex = 7;
});
});
super.initState();
}
//点位信息数据
//{
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆",
// "dwzt": "正常"
//},
// Widget getDropdownButton() {
// //DropdownMenuItem项目文本list
// List<String> itemList = [
// '主键ID',
// '点位IP',
// '点位名称',
// '点位编号',
// '点位信息',
// '点位坐标',
// '点位描述',
// '点位状态',
// ];
Widget _getListTile(BuildContext context, indexRecord) {
List listCoordinate = listSbglGetList2[indexRecord]["dwzb"].trim().split('|');
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: Text(
"${listSbglGetList2[indexRecord]['dwbh'].toString()}. ${listSbglGetList2[indexRecord]['dwmc']}",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold)),
subtitle: Text(
'dwIP:${listSbglGetList2[indexRecord]['dwip']},${listSbglGetList2[indexRecord]['dwzt']}',
style: TextStyle(fontSize: 14)),
trailing: Container(
width: 160,
child: Text(
'${listSbglGetList2[indexRecord]['dwms']}' +
', 经纬度:${listCoordinate[0]}、${listCoordinate[1]}',
maxLines: 2,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: 14),
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {
int ret = await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DwxxContent(
title: '设备管理信息详情',
index: indexRecord,
hyshlx: widget.hyshlx,
),
),
);
print('ret = $ret');
},
),
Divider(height: 1.0),
],
);
}
ScrollController _controller = ScrollController(); //ListView控制器
bool isLoading = false; //正在处理下载数据、跳转到首项、跳转到尾项等操作
int firstIndex = 0; //ListView当前显示页面首项0基序号
int lastIndex = 0; //ListView当前显示页面末项0基序号
int itemOnPage = 8; //估计一屏显示的项目数量
Widget getIconButton({IconData iconData, var onPressed, double iconSize = 22}) {
return SizedBox(
height: iconSize,
width: iconSize + 10,
child: IconButton(
padding: EdgeInsets.all(0.0),
icon: Icon(iconData, size: iconSize, color: Colors.white),
onPressed: onPressed,
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// automaticallyImplyLeading: false,
// centerTitle: true,
// //leading: Text(''),
// titleSpacing: 0.0,
// //设置title的左边距
// title: Padding(
// padding: EdgeInsets.only(left: 0, right: 0),
// child: Row(
// //mainAxisAlignment: MainAxisAlignment.start,
// children: [
// getIconAndTextButton(
// iconData: Icons.arrow_back,
// onPress: () {
// Navigator.pop(context);
// },
// ),
// Expanded(
// child: Text("${mapHyshlx[hyshlx]['text']}",
// textAlign: TextAlign.left,
// overflow: TextOverflow.ellipsis,
// style: widget.hyshlx == 'fhycx' ? TextStyle(fontSize: 16) : null),
// ),
// SizedBox(width: 5),
// ],
// ),
// ),
// actions: <Widget>[
// getDropdownButton(),
// SizedBox(width: 10),
// // getIconButton(
// // iconData: Icons.cloud_download,
// // onPressed: !isLoading
// // ? () async {
// // if (isLoading) {
// // return;
// // }
// // isLoading = true;
// // try_setState();
// // //print("I Pressed the Iconbutton");
// // int oldItems = listSbglGetList2.length;
// // for (int i = 0; i < 10; i++) {
// // List list = await getPageList();
// // if (list.length > 0) {
// // listSbglGetList2.addAll(list); //加载累加
// // } else {
// // break;
// // }
// // }
// // Future.delayed(const Duration(milliseconds: 1000), () async {
// // if (listSbglGetList2.length > oldItems) {
// // eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
// // Fluttertoast.showToast(
// // msg: '新增 ${listSbglGetList2.length - oldItems} 条数据下载完成!',
// // toastLength: Toast.LENGTH_SHORT,
// // gravity: ToastGravity.CENTER,
// // );
// //
// // //按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
// // _listSort();
// // }
// // isLoading = false;
// // try_setState();
// // });
// // }
// // : null,
// // ),
// SizedBox(width: 10),
// getIconButton(
// iconData: Icons.vertical_align_top_outlined,
// onPressed: (!isLoading && (firstIndex > 0)) //未到顶部
// ? () async {
// if (isLoading) {
// return;
// }
// isLoading = true;
// try_setState();
//
// //必须延时执行,否则不能及时完成按钮状态更新
// Timer(
// Duration(milliseconds: 500),
// () {
// _controller.jumpTo(_controller.position.minScrollExtent);
// },
// );
//
// Timer(
// Duration(milliseconds: 1000),
// () {
// // Fluttertoast.showToast(
// // msg: '已经跳转到开头记录!',
// // toastLength: Toast.LENGTH_SHORT,
// // gravity: ToastGravity.CENTER,
// // );
// firstIndex = 0;
// lastIndex = itemOnPage - 1; //0基序号,所以需要减1
// isLoading = false;
// try_setState();
// },
// );
// }
// : null,
// ),
// SizedBox(width: 10),
// getIconButton(
// iconData: Icons.vertical_align_bottom_outlined,
// onPressed: (!isLoading && (lastIndex < listSbglGetList2.length)) //未到尾部
// ? () async {
// if (isLoading) {
// return;
// }
// isLoading = true;
// try_setState();
//
// //必须延时执行,否则不能及时完成按钮状态更新
// Timer(
// Duration(milliseconds: 500),
// () {
// _controller.jumpTo(_controller.position.maxScrollExtent);
// },
// );
//
// Timer(
// Duration(milliseconds: 1000),
// () {
// // Fluttertoast.showToast(
// // msg: '已经跳转到末尾记录!',
// // toastLength: Toast.LENGTH_SHORT,
// // gravity: ToastGravity.CENTER,
// // );
// //0基序号需要减1,再加上底部有一组显示信息,所以需要减2
// firstIndex = listSbglGetList2.length - itemOnPage - 2;
// lastIndex = listSbglGetList2.length;
// isLoading = false;
// try_setState();
// },
// );
// }
// : null,
// ),
// SizedBox(width: 10),
// ],
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // here the desired height
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
//leading: Text(''),
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
//1、第1行组件,工具按钮
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
//1.1、返回按钮
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
//1.2、title 显示控制
Expanded(
child: Text("${mapHyshlx[hyshlx]['text']}",
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.white, fontSize: 20)),
),
SizedBox(width: 5),
],
),
),
//1.3、尾部工具按钮组
actions: <Widget>[
//getDropdownButton(),
getIconButton(
iconData: Icons.cloud_download,
onPressed: !isLoading
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//print("I Pressed the Iconbutton");
int oldItems = listSbglGetList2.length;
for (int i = 0; i < 10; i++) {
List list = await getPageList();
if (list.length > 0) {
listSbglGetList2.addAll(list); //加载累加
} else {
break;
}
}
Future.delayed(const Duration(milliseconds: 1000), () async {
if (listSbglGetList2.length > oldItems) {
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
Fluttertoast.showToast(
msg: '新增 ${listSbglGetList2.length - oldItems} 条数据下载完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
//按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
_listSort();
//_controller.jumpTo(1); // _controller.position 能够有效刷新,人眼可察觉的滚动
_controller.jumpTo(0.001); // _controller.position 完美解决有效刷新,而且人眼不可见察觉滚动
//第二次跳转必须延时,否则 _controller.position 不能有效刷新
Future.delayed(Duration(milliseconds: 500), () {
_controller.jumpTo(_controller.position.minScrollExtent);
});
}
isLoading = false;
try_setState();
});
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
getIconButton(
iconData: Icons.vertical_align_top_outlined,
onPressed: (!isLoading && (firstIndex > 0)) //未到顶部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.minScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到开头记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
firstIndex = 0;
lastIndex = itemOnPage - 1; //0基序号,所以需要减1
isLoading = false;
try_setState();
},
);
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
getIconButton(
iconData: Icons.vertical_align_bottom_outlined,
onPressed: (!isLoading && (lastIndex < listSbglGetList2.length)) //未到尾部
? () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
//必须延时执行,否则不能及时完成按钮状态更新
Timer(
Duration(milliseconds: 500),
() {
_controller.jumpTo(_controller.position.maxScrollExtent);
},
);
Timer(
Duration(milliseconds: 1000),
() {
// Fluttertoast.showToast(
// msg: '已经跳转到末尾记录!',
// toastLength: Toast.LENGTH_SHORT,
// gravity: ToastGravity.CENTER,
// );
//0基序号需要减1,再加上底部有一组显示信息,所以需要减2
firstIndex = listSbglGetList2.length - itemOnPage - 2;
lastIndex = listSbglGetList2.length;
isLoading = false;
try_setState();
},
);
}
: null,
),
SizedBox(width: ScreenUtil().setWidth(32)),
],
),
),
body: Column(children: [
//2、第2行排序按钮
Container(
height: ScreenUtil().setHeight(142),
decoration: new BoxDecoration(border: new Border.all(color: Colors.red)),
child: Row(
children: [
SizedBox(width: ScreenUtil().setWidth(50)),
Text('排序', style: TextStyle(fontSize: 18)),
Expanded(child: SizedBox.shrink()),
getDropdownButton(),
SizedBox(width: ScreenUtil().setWidth(20)),
],
),
),
(0 == listSbglGetList2.length)
? getMoreWidget(color: Colors.black38)
: Expanded(
child: EasyRefresh(
child: ListView.custom(
//itemExtent: 75.0, //列表项高度
controller: _controller,
cacheExtent: 1.0, // 只有设置了1.0 才能够准确的标记 position 位置
childrenDelegate: MyChildrenDelegate(
_getListTile,
childCount: listSbglGetList2.length,
),
),
onRefresh: () async {
// await Future.delayed(const Duration(seconds: 1), () async {
// iPage = 0;
// //await getWzxxGetList();
// listSbglGetList2 = await getPageList();
// eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
// });
},
onLoad: () async {
if (isLoading) {
return;
}
isLoading = true;
try_setState();
print('iPage = $iPage');
await Future.delayed(const Duration(seconds: 1), () async {
//await getWzxxGetList();
List list = await getPageList();
if (list.length > 0) {
listSbglGetList2.addAll(list); //加载累加
eventBus.fire(WzxxDataAuditEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));
}
isLoading = false;
try_setState();
});
},
header: getHeader(),
footer: getFooter(),
),
)
]),
);
}
//DropdownButton需要设置初始值的时候,初始值必须是显示列表里面的值,否则会导致弹出框异常。
// 比如说:你的DropdownButton的items属性使用的是list这个列表里面的值,那么你的初始值应该在list[index]里面取,要不就会报错。
//
// There should be exactly one item with [DropdownButton]'s value: 0.0.
// Either zero or 2 or more [DropdownMenuItem]s were detected with the same value
// 'package:flutter/src/material/dropdown.dart':
// Failed assertion: line 834 pos 15: 'items == null || items.isEmpty || value == null ||
// items.where((DropdownMenuItem<T> item) {
// return item.value == value;
// }).length == 1'
String _selectedValue = '点位编号';
bool _descending = false; //默认升序排列
Widget _getImage(String _image) {
return Container(
margin: EdgeInsets.only(),
height: ScreenUtil().setWidth(48),
width: ScreenUtil().setWidth(48),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(_image,
fit: BoxFit.cover, color: isLoading ? Theme.of(context).disabledColor : null));
}
//按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
Future _listSort({bool bShowToast = false}) {
if (!isLoading && listSbglGetList2.length > 0) {
isLoading = true;
try_setState();
switch (_selectedValue) {
default:
if (_descending) {
//按_selectedValue排序,降序
listSbglGetList2.sort((a, b) =>
(b[mapWzxxDataText[_selectedValue]]).compareTo(a[mapWzxxDataText[_selectedValue]]));
} else {
//按_selectedValue排序,升序
listSbglGetList2.sort((a, b) =>
(a[mapWzxxDataText[_selectedValue]]).compareTo(b[mapWzxxDataText[_selectedValue]]));
}
break;
}
Future.delayed(const Duration(milliseconds: 1000), () {
if (bShowToast) {
Fluttertoast.showToast(
msg: '按“${_selectedValue}”${_descending ? '降序' : '升序'}排列完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
isLoading = false;
try_setState(); //避免如下异常报错
});
}
}
Widget getDropdownButtonItemText(String item) {
return Padding(
padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(3)),
child: Row(
//crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
alignment: Alignment(0, 0),
padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
child: item == _selectedValue
? _descending
? _getImage('assets/images/descending.png')
: _getImage('assets/images/ascending.png')
// ? Icon(Icons.arrow_downward_outlined, size: 20)
// : Icon(Icons.arrow_upward_outlined, size: 20)
: SizedBox(),
),
SizedBox(
width: ScreenUtil().setWidth(10),
),
Container(
//alignment: Alignment(0, -1),
child: Text(item,
style: TextStyle(
fontSize: 18,
color: isLoading
? Theme.of(context).disabledColor
: item == _selectedValue
? Colors.blue
: null)),
// style: isLoading
// ? TextStyle(color: Theme.of(context).disabledColor)
// : (item == _selectedValue ? TextStyle(color: Colors.blue) : null)),
),
],
),
);
}
//点位信息数据
//{
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆",
// "dwzt": "正常"
//},
Widget getDropdownButton() {
//DropdownMenuItem项目文本list
List<String> itemList = [
'主键ID',
'点位IP',
'点位名称',
'点位编号',
'点位信息',
'点位坐标',
'点位描述',
'点位状态',
];
//添加按'推送状态'排序
if (hyshlx != 'dwxx') {
// itemList.removeLast();
// itemList.addAll(['推送状态', '主键ID']);
}
//获取DropdownMenuItem项目组件list
List<DropdownMenuItem<String>> _dropDownMenuItems =
itemList.map<DropdownMenuItem<String>>((String item) {
return DropdownMenuItem<String>(
value: item,
child: getDropdownButtonItemText(item),
);
}).toList();
return Padding(
padding: EdgeInsets.only(top: 0, bottom: 0),
child: Container(
alignment: Alignment(0, 0),
width: 135,
margin: EdgeInsets.only(bottom: 0),
padding: EdgeInsets.only(left: 0, bottom: 0),
// decoration: BoxDecoration(
// border: Border.all(width: 0),
// //边框圆角设置
// borderRadius:
// BorderRadius.vertical(top: Radius.elliptical(2, 2), bottom: Radius.elliptical(2, 2)),
// ),
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
child: DropdownButtonHideUnderline(
child: DropdownButton<String>(
iconSize: ScreenUtil().setHeight(100),
//itemHeight: ScreenUtil().setHeight(372),
isDense: true,
value: _selectedValue,
items: _dropDownMenuItems,
onChanged: (String selectedValue) {
if (isLoading) {
return;
}
if (_selectedValue == selectedValue) {
_descending = !_descending;
} else {
_descending = true;
}
_selectedValue = selectedValue;
print('_selectedValue = $_selectedValue');
//按抓拍次数排序,降序
// listSbglGetList2.sort((a, b) => (b["yjxx_id"].split(',').length.toString())
// .compareTo(a["yjxx_id"].split(',').length.toString()));
//按照用户选择的_selectedValue、_descending对listSbglGetList2进行排序,并延时更新
_listSort();
},
),
),
),
);
}
}
//https://blog.csdn.net/u014803467/article/details/103750018
//Flutter 使用SliverChildBuilderDelegate获取ListView的第一个和最后一个可见Item序号
// 秋名山交警X 2019-12-28 23:52:52
class _SaltedValueKey extends ValueKey<Key> {
const _SaltedValueKey(Key key)
: assert(key != null),
super(key);
}
class MyChildrenDelegate extends SliverChildBuilderDelegate {
MyChildrenDelegate(
Widget Function(BuildContext, int) builder, {
int childCount,
bool addAutomaticKeepAlive = true,
bool addRepaintBoundaries = true,
}) : super(builder,
childCount: childCount,
addAutomaticKeepAlives: addAutomaticKeepAlive,
addRepaintBoundaries: addRepaintBoundaries);
// Return a Widget for the given Exception
Widget _createErrorWidget(dynamic exception, StackTrace stackTrace) {
final FlutterErrorDetails details = FlutterErrorDetails(
exception: exception,
stack: stackTrace,
library: 'widgets library',
context: ErrorDescription('building'),
);
FlutterError.reportError(details);
return ErrorWidget.builder(details);
}
@override
Widget build(BuildContext context, int index) {
assert(builder != null);
if (index < 0 || (childCount != null && index >= childCount)) return null;
Widget child;
try {
child = builder(context, index);
} catch (exception, stackTrace) {
child = _createErrorWidget(exception, stackTrace);
}
if (child == null) return null;
final Key key = child.key != null ? _SaltedValueKey(child.key) : null;
if (addRepaintBoundaries) child = RepaintBoundary(child: child);
if (addSemanticIndexes) {
final int semanticIndex = semanticIndexCallback(child, index);
if (semanticIndex != null)
child = IndexedSemantics(index: semanticIndex + semanticIndexOffset, child: child);
}
if (addAutomaticKeepAlives) child = AutomaticKeepAlive(child: child);
return KeyedSubtree(child: child, key: key);
}
@override
void didFinishLayout(int _firstIndex, int _lastIndex) {
// TODO: implement didFinishLayout
super.didFinishLayout(_firstIndex, _lastIndex);
}
///监听 在可见的列表中 显示的第一个位置和最后一个位置
@override
double estimateMaxScrollOffset(
int _firstIndex, int _lastIndex, double _leadingScrollOffset, double _trailingScrollOffset) {
//违章信息Listview滚动广播
eventBus.fire(WzxxDataScrollEvent(_firstIndex, _lastIndex));
return super.estimateMaxScrollOffset(
_firstIndex, _lastIndex, _leadingScrollOffset, _trailingScrollOffset);
}
}
+688
View File
@@ -0,0 +1,688 @@
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
///获取车流量日统计数据
bool cllRStatisDataGeting = false; //正在获取车流量日统计数据,禁止重入
bool cllRStatisDataOk = false; //listCllrtjStatis 中的数据是否准备好
//List listCllrtjStatis = [];
// [
// {
// "dwbh": 4,
// "dwmc": "一曼路",
// "dwip": "172.16.3.4"
// "all": "770742",
// "cllmx": [
// {
// "day": "2021-04-12",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "17760",
// "am": "1272",
// "pm": "3153"
// },
// {
// "day": "2021-04-11",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "18005",
// "am": "1677",
// "pm": "2275"
// },
// // ...
// ]
// },
// {
// "dwbh": 5,
// "dwmc": "柏溪收费站",
// "dwip": "172.16.3.5"
// "all": "770742",
// "cllmx": [
// {
// "day": "2021-04-12",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "17760",
// "am": "1272",
// "pm": "3153"
// },
// {
// "day": "2021-04-11",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "18005",
// "am": "1677",
// "pm": "2275"
// },
// // ...
// ]
// },
// ]
///获取抓拍统计数据
List listZptjStatis = [];
///获取审核黑烟车统计数据
List listSh_hyc_tjStatis = [];
///获取审核黑烟车统计数据
List listClltjStatis = [];
///获取车流量日统计数据
List listCllrtjStatis = [];
bool statisDataOk = false; //listCllrtjStatis 中的数据是否准备好
Map mapCllrtjStatis = {};
/*
{
"total": 6635167,
"am": 713074,
"pm": 981656,
"view": [
{
"dwip": "172.16.3.1",
"dw_all": 701120,
"dw_am": 76210,
"dw_pm": 105153,
"cllmx": [
{
"day": "2021-05-25",
"am_order": "0730:0930",
"pm_order": "1730:1930",
"all": "24190",
"am": "2148",
"pm": "5173"
},
{
"day": "2021-05-24",
"am_order": "0730:0930",
"pm_order": "1730:1930",
"all": "20254",
"am": "1825",
"pm": "3975"
},
...
},
{
"dwip": "172.16.3.2",
"dw_all": 533990,
"dw_am": 65276,
"dw_pm": 78055,
"cllmx": [
{
"day": "2021-05-25",
"am_order": "0730:0930",
"pm_order": "1730:1930",
"all": "16355",
"am": "1375",
"pm": "3029"
},
{
"day": "2021-05-24",
"am_order": "0730:0930",
"pm_order": "1730:1930",
"all": "15997",
"am": "1797",
"pm": "2216"
},
...
*/
// [
// {
// "dwbh": 4,
// "dwmc": "一曼路",
// "dwip": "172.16.3.4"
// "all": "770742",
// "cllmx": [
// {
// "day": "2021-04-12",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "17760",
// "am": "1272",
// "pm": "3153"
// },
// {
// "day": "2021-04-11",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "18005",
// "am": "1677",
// "pm": "2275"
// },
// // ...
// ]
// },
// {
// "dwbh": 5,
// "dwmc": "柏溪收费站",
// "dwip": "172.16.3.5"
// "all": "770742",
// "cllmx": [
// {
// "day": "2021-04-12",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "17760",
// "am": "1272",
// "pm": "3153"
// },
// {
// "day": "2021-04-11",
// "am_order": "0730:0930",
// "pm_order": "1730:1930",
// "all": "18005",
// "am": "1677",
// "pm": "2275"
// },
// // ...
// ]
// },
// ]
// 一次性获取所有点位的统计数据存入 listCllrtjStatis
Future getCllrtjStatisNew(String statisType) async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listCllrtjStatis.clear();
mapCllrtjStatis = await getStatisData(statisType: statisType);
listCllrtjStatis = mapCllrtjStatis["view"];
// int len = listDwinfoGetList2.length;
// for (int i = 0; i < len; i++) {
// Map map = await getStatisData(statisType: statisType, ip: listDwinfoGetList2[i]['dwip']);
// map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
// map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
// map['dwip'] = listDwinfoGetList2[i]['dwip'];
// listCllrtjStatis.add(map);
// }
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
//遍历 listDwinfoGetList2 中所有点位,得到对应点位 ip 的统计数据存入 listCllrtjStatis
Future getCllrtjStatis(String statisType) async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listCllrtjStatis.clear();
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map = await getStatisData(statisType: statisType, ip: listDwinfoGetList2[i]['dwip']);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listCllrtjStatis.add(map);
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
//遍历 listDwinfoGetList2 中所有点位,得到对应点位 ip 的统计数据存入 listZptjStatis
Future getZptjStatis(String statisType) async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listZptjStatis.clear();
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map = await getStatisData(statisType: statisType, ip: listDwinfoGetList2[i]['dwip']);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listZptjStatis.add(map);
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
//在Dart语言中,如何通过值获取MAP键?mapTjDataText
String getKey(String value) {
String key = mapTjDataText.keys.firstWhere((k) => mapTjDataText[k] == value, orElse: () => null);
}
Map<String, String> mapTjDataText = {
"dwmc": '点位名称',
"dwbh": '点位编号',
"dwip": '点位IP',
"today": '今日',
"all": '总共',
"total": '已审核',
"sends": '已推送'
};
//////////////////////////////////////////////////////////////////
///独立获取抓拍统计数据
List listZptjStatisAlone = [];
List listTodayZpjl = []; //今日抓拍记录列表
//遍历 listDwinfoGetList2 中所有点位,独立得到对应点位 ip 的统计数据存入 listZptjStatisNew
Future getZptjStatisAlone() async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listZptjStatisAlone.clear();
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map = await getStatisData(statisType: 'zptj', ip: listDwinfoGetList2[i]['dwip']);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listZptjStatisAlone.add(map);
// if (listZptjStatisAlone.length >= dwSum) {
// //发送统计数据已更新广播
// eventBus.fire(StatisDataUpdate('统计数据已更新'));
// }
getAllSum('today', listZptjStatisAlone).then((value) {
//mapStatisInfo['今日抓拍'] = value[1];
listTodayZpjl = value[2];
//try_setState();
});
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
///独立获取今日审核统计数据
List listTodayShtj = [];
List listTodayChjl = []; //今日初审记录列表
List listTodayFhjl = []; //今日复审记录列表
List listTodayTsjl = []; //今日推送记录列表
//遍历 listDwinfoGetList2 中所有点位,独立得到对应点位 ip 的统计数据存入 listShtjStatisNew
Future getTodayShtj() async {
//今日审核统计数据
//{
// "total": 0,"today": 0,
// "sends": 0,"all": 72
// "csnum": 0,"dwbh": 1,
// "fsnum": 0"dwmc": "江北振兴大道",
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listTodayShtj.clear();
DateTime dateTime = DateTime.now();
String _mouth = dateTime.month.toString().trim();
if (_mouth.length == 1) {
_mouth = '0' + _mouth;
}
String _day = dateTime.day.toString().trim();
if (_day.length == 1) {
_day = '0' + _day;
}
String date = '${dateTime.year}-${_mouth}-${_day}';
print('date = $date');
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map =
await getStatisData(statisType: 'sh_hyc_tj', ip: listDwinfoGetList2[i]['dwip'], date: date);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listTodayShtj.add(map);
// if (listTodayShtj.length >= dwSum) {
// print('listTodayShtj = $listTodayShtj');
// //发送统计数据已更新广播
// eventBus.fire(StatisDataUpdate('统计数据已更新'));
// }
getAllSum('csnum', listTodayShtj).then((value) {
//mapStatisInfo['今日初审'] = value[1];
listTodayChjl = value[2];
//try_setState();
});
getAllSum('fsnum', listTodayShtj).then((value) {
//mapStatisInfo['今日复审'] = value[1];
listTodayFhjl = value[2];
//try_setState();
});
getAllSum('sends', listTodayShtj).then((value) {
//mapStatisInfo['今日推送'] = value[1];
listTodayTsjl = value[2];
//try_setState();
});
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
///独立获取审核统计数据
List listShtjStatisAlone = [];
//遍历 listDwinfoGetList2 中所有点位,独立得到对应点位 ip 的统计数据存入 listShtjStatisNew
Future getShtjStatisAlone() async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listShtjStatisAlone.clear();
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map = await getStatisData(statisType: 'sh_hyc_tj', ip: listDwinfoGetList2[i]['dwip']);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listShtjStatisAlone.add(map);
// if (listShtjStatisAlone.length >= dwSum) {
// //发送统计数据已更新广播
// eventBus.fire(StatisDataUpdate('统计数据已更新'));
// }
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
///独立获取车流量统计数据
List listClltjStatisAlone = [];
//遍历 listDwinfoGetList2 中所有点位,独立得到对应点位 ip 的统计数据存入 listShtjStatisNew
Future getClltjStatisAlone() async {
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据,返回 Map
//Future getStatisData({@required String statisType, @required String ip}) async {
listClltjStatisAlone.clear();
int len = listDwinfoGetList2.length;
for (int i = 0; i < len; i++) {
Map map = await getStatisData(statisType: 'clltj', ip: listDwinfoGetList2[i]['dwip']);
map['dwbh'] = listDwinfoGetList2[i]['dwbh'];
map['dwmc'] = listDwinfoGetList2[i]['dwmc'];
map['dwip'] = listDwinfoGetList2[i]['dwip'];
listClltjStatisAlone.add(map);
// if (listClltjStatisAlone.length >= dwSum) {
// //发送统计数据已更新广播
// eventBus.fire(StatisDataUpdate('统计数据已更新'));
// }
}
//print('listZptjStatis = ${listZptjStatis}');
//StorageDataToFile.writeCounter(json_print(listZptjStatis, 1));
}
//////////////////////////////////////////////////////////////////
///获取所有统计数据
List listAllStatisData = [];
///车流量日统计数据类
var trinityData;
// 实现多个基于 Page1_Works 构建的页面共享统计数据
Future startGetStatisDataNew() async {
///获取点位信息数据
//listDwinfoGetList2.clear();
if (listDwinfoGetList2.isEmpty) {
//若没有读取点位数据,便需要先读取
getThePageList(theHyshlx: 'dwxx').then((value) {
listDwinfoGetList2 = value;
print('listDwinfoGetList2 = \n$listDwinfoGetList2');
dwSum = listDwinfoGetList2.length;
//获取记录数据
getZptjStatisAlone();
getTodayShtj();
getClltjStatisAlone();
//获取统计数据
getAllStatisData().then((value) {
listAllStatisData = value;
eventBus.fire(StatisDataUpdate('统计数据已更新'));
});
});
} else {
if (mapStatisInfo['今日抓拍'] < 0) {
//获取记录数据
getZptjStatisAlone();
getTodayShtj();
getClltjStatisAlone();
//获取统计数据
getAllStatisData().then((value) {
listAllStatisData = value;
eventBus.fire(StatisDataUpdate('统计数据已更新'));
});
} else {
//发送统计数据已更新广播
eventBus.fire(StatisDataUpdate('统计数据已更新'));
}
}
}
Map<String, double> mapStatisInfo = {
'今日抓拍': -1,
'今日初审': -1,
'今日复审': -1,
'今日推送': -1,
'今日车流': -1,
};
//得到所有5项统计数据
//适用的字段:抓拍统计的'today'、all;审核统计的"total"、"sends";
Future getAllSumNew() async {
int items = 0;
mapStatisInfo['今日抓拍'] = 0;
mapStatisInfo['今日初审'] = 0;
mapStatisInfo['今日复审'] = 0;
mapStatisInfo['今日推送'] = 0;
mapStatisInfo['今日车流'] = 0;
for (var item in listAllStatisData) {
items++;
if (item["zp_today"] > 0) {
//listRecords.addAll(item[field]["data"]); //将记录详情存入listRecords
mapStatisInfo['今日抓拍'] += item["zp_today"];
}
if (item["csnum"] > 0) {
mapStatisInfo['今日初审'] += item["csnum"];
}
if (item["fsnum"] > 0) {
mapStatisInfo['今日复审'] += item["fsnum"];
}
if (item["sends"] > 0) {
mapStatisInfo['今日推送'] += item["sends"];
}
if (item["cll_today"] > 0) {
mapStatisInfo['今日车流'] += item["cll_today"];
}
}
mapStatisInfo['今日车流'] = mapStatisInfo['今日车流'] / 10000;
// 统计点位数(未用),总计,记录列表
//return [items, sum, listRecords];
}
/*
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 52,
"zp_today": 1,
"sends": 0,
"send_all": 33,
"csnum": 1,
"fsnum": 0,
"cll_today": 6420,
"cll_all": 3225733
},
{
"id": 2,
"dwip": "172.16.3.2",
"dwmc": "石马溪桥",
"zp_all": 377,
"hyc_all": 370,
"zp_today": 1,
"sends": 0,
"send_all": 204,
"csnum": 1,
"fsnum": 0,
"cll_today": 3430,
"cll_all": 2127839
},
...
]
*/
// 实现多个基于 Page1_Works 构建的页面共享统计数据
Future startGetStatisDataOld() async {
///获取点位信息数据
//listDwinfoGetList2.clear();
if (listDwinfoGetList2.isEmpty) {
//若没有读取点位数据,便需要先读取
getThePageList(theHyshlx: 'dwxx').then((value) {
listDwinfoGetList2 = value;
print('listDwinfoGetList2 = \n$listDwinfoGetList2');
dwSum = listDwinfoGetList2.length;
getZptjStatisAlone();
getTodayShtj();
getClltjStatisAlone();
});
} else {
if (mapStatisInfo['今日抓拍'] < 0) {
getZptjStatisAlone();
} else {
//发送统计数据已更新广播
eventBus.fire(StatisDataUpdate('统计数据已更新'));
}
if (mapStatisInfo['今日初审'] < 0) {
getTodayShtj();
} else {
//发送统计数据已更新广播
eventBus.fire(StatisDataUpdate('统计数据已更新'));
}
if (mapStatisInfo['今日车流'] < 0) {
getClltjStatisAlone();
} else {
//发送统计数据已更新广播
eventBus.fire(StatisDataUpdate('统计数据已更新'));
}
}
}
//获取已审核黑烟车统计数据:App.Car_Statis.GetStaHyc
//{
// "ret": 200,
// "data": {
// "total": 40,
// "sends": {
// "total": 0,
// "data": []
// },
// "csnum": {
// "total": 0,
// "data": []
// },
// "fsnum": {
// "total": 0,
// "data": []
// }
// },
// "msg": ""
// }
//获取抓拍统计数据:App.Car_Statis.GetStaYjxx
//{
// "ret": 200,
// "data": {
// "today": {
// "total": 0,
// "data": []
// },
// "all": 40
// },
// "msg": ""
// }
//得到 listStatis[field] 的统计数据,
//适用的字段:抓拍统计的'today'、all;审核统计的"total"、"sends";
Future getAllSum(String field, List listStatis) async {
int items = 0;
int sum = 0;
List listRecords = []; //记录详情存入
for (var item in listStatis) {
if (item[field]["total"] > 0) {
items++;
listRecords.addAll(item[field]["data"]); //将记录详情存入listRecords
sum += item[field]["total"];
}
}
return [items, sum, listRecords];
}
//获取车流量统计数据:App.Car_Statis.GetStaCll
//{
// "ret": 200,
// "data": {
// "today": 7010,
// "all": 1640350
// },
// "msg": ""
//}
//得到 listStatis[field] 的统计数据,
//适用的字段:车流量统计的'today'、all
Future getAllSumCll(String field, List listStatis) async {
int items = 0;
int sum = 0;
for (var item in listStatis) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
//////////////////////////////////////////////////////////////////
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,778 @@
//import '../../../widget/player_pro.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_drag_scale/flutter_drag_scale.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/widget/my_superplayer.dart';
import 'package:keyboard_avoider/keyboard_avoider.dart';
//
import '../../../components/commonFun.dart';
import '../../../components/doJSON.dart';
import '../../../components/hyxx_data_handle.dart';
// "today": {
// "total": 4,
// "data": [
// {
// "id": 428549,
// "car_number": "川15A2563",
// "cpys": "绿色",
// "zpsj": "2021-04-04 11:31:11",
// "dwip": "172.16.3.3",
// "dwms": "岷江南路森林小区附近",
// "cplx": "农用车",
// "lgmzs": 3,
// "pic_url": "/wwwroot/admin/Api/wwwroot/public/uploads/e936524e92f90541cbaeca3b092c95be.jpg",
// "video_url": "video/3_6063_20210404_113111_川15A2563.mp4"
// },
class TodayListZpjlContent extends StatefulWidget {
TodayListZpjlContent({
@required this.hyshlx,
@required this.num,
@required this.text,
@required this.mapZpjl,
this.tsztText = '',
Key key,
}) : super(key: key);
String hyshlx;
String num;
String text;
Map mapZpjl;
String tsztText;
_TodayListZpjlPageState createState() => _TodayListZpjlPageState();
}
//用TabController实现顶部tab切换
class _TodayListZpjlPageState extends State<TodayListZpjlContent> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
dispose() {
super.dispose();
}
BuildContext _context;
//flutter_screenUtil 4.x 用法,ScreenUtil.screenWidth (sdk>=2.6 : 1.sw) //设备宽度
double _screenWidth = 1.sw;
double _marginLeft = 25;
double _marginCenter = 35;
double _fontSize = 16;
double _widthLeft = 40; // = _screenWidth / 3;
double _iconSize = 18;
double _stampSize = 100;
double _listTileHeight = 30;
Color _iconColor = Colors.blue;
double _marginVer = 10;
Map _mapTsjjGetTsStatus = {};
Map mapName = {};
void initState() {
_context = context;
_widthLeft = _screenWidth / 2.6;
//getListFlields();
//得到字段名称
mapName['plate_id'] = widget.hyshlx == 'jrzp' ? 'car_number' : 'plate_id';
mapName['plate_color'] = widget.hyshlx == 'jrzp' ? 'cpys' : 'plate_color';
imageWztp = getWztp(); //得到违章图片
super.initState();
}
double _radioImage = 9 / 16;
// 使用 cached_network_image 插件实现网络图片缓存
// 使用 flutter_drag_scale 实现可缩放可拖拽双击放大的图片功能。PhotoView插件不好用,有问题
Widget getNetworkImage(String url) {
return CachedNetworkImage(
imageUrl: url,
alignment: Alignment.topCenter,
imageBuilder: (context, imageProvider) => DragScaleContainer(
doubleTapStillScale: true, child: Image(image: imageProvider)
// child: Image(
// image: NetworkImage(
// 'http://h.hiphotos.baidu.com/zhidao/wh%3D450%2C600/sign=0d023672312ac65c67506e77cec29e27/9f2f070828381f30dea167bbad014c086e06f06c.jpg'),
// ),
),
// imageBuilder: (context, imageProvider) => PhotoView(
// imageProvider: imageProvider,
// ),
//placeholder: (context, url) => CircularProgressIndicator(),
placeholder: (context, url) =>
getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0),
errorWidget: (context, url, error) => Icon(Icons.error),
);
}
// 167 50 3.34
Widget getLgmzs(int lgmzs, {double width = 127, double height = 127}) {
int _rgb = (255 * (5 - lgmzs)) ~/ 5;
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 4),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('$lgmzs级${lgmzs * 20}%', style: TextStyle(fontSize: 10)),
//SizedBox(height: 0),
Container(
width: ScreenUtil().setWidth(66),
height: ScreenUtil().setHeight(66),
decoration: BoxDecoration(
border: Border.all(color: Colors.grey),
color: Color.fromRGBO(_rgb, _rgb, _rgb, 1.0),
borderRadius: new BorderRadius.circular(0),
),
)
],
),
),
Positioned(
top: ScreenUtil().setHeight(4),
child: Container(
width: ScreenUtil().setWidth(width),
height: ScreenUtil().setHeight(height - 8),
padding: EdgeInsets.only(
right: ScreenUtil().setWidth(6), left: ScreenUtil().setWidth(6), top: 0, bottom: 0),
decoration: BoxDecoration(
border: Border.all(
color: (lgmzs == widget.mapZpjl['lgmzs'])
? Colors.red
: Color.fromRGBO(244, 244, 244, 1),
width: 2),
//color: Colors.lightBlue,
borderRadius: new BorderRadius.circular(3.0),
),
),
)
],
);
}
//得到tsjj页面组件
//1、得到格林曼黑度标准和视频播放按钮组件
Widget getHdAndPlay() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getLgmzs(0),
getLgmzs(1),
getLgmzs(2),
getLgmzs(3),
getLgmzs(4),
getLgmzs(5, width: 153),
getIconBtnSizeX(
height: 104,
//getIconBtnSizeX 中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 168,
text: "视频",
textSize: 12,
circular: 4,
color: Color.fromRGBO(52, 157, 237, 1),
onTop: () async {
if (Playing) {
//禁止同时启动两次播放器
return;
}
Playing = true; //禁止同时启动两次播放器
urlnew = getMediaUrl(widget.mapZpjl['video_url']);
//获取视频地址失败
if (!isVideoUrl(urlnew)) {
return;
}
Navigator.of(_context).push(MaterialPageRoute(
builder: (context) => SuperPlayerPage(
loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
url: urlnew,
title:
'${widget.text}视频${widget.num}\n${widget.mapZpjl[mapName['plate_id']]}(${getDwmc(widget.mapZpjl['dwip'])})')));
// Navigator.of(_context).push(MaterialPageRoute(
// builder: (context) => PlayerProNew(
// loop: 0, //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
// url: urlnew,
// title:
// '${widget.text}视频${widget.num}\n${widget.mapZpjl[mapName['plate_id']]}(${getDwmc(widget.mapZpjl['dwip'])})')));
},
),
SizedBox(width: ScreenUtil().setWidth(15)),
],
);
}
Widget imageWztp;
//2、得到违章图片组件
Widget getWztp() {
//ratioList[index] = 0.5714285714285714
return Stack(
children: [
Container(
width: ScreenUtil().setWidth(1022),
//height: ScreenUtil().setHeight(639),
//height: ScreenUtil().setHeight(22 + 1022 * _radioImage),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
decoration: BoxDecoration(
//color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
),
Positioned(
//left: ScreenUtil().setWidth(_marginLeft),
top: ScreenUtil().setHeight(_marginLeft),
child: Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(30 + 1022 * _radioImage),
child: getNetworkImage(getMediaUrl(widget.mapZpjl['pic_url'])),
),
)
],
);
}
// void printScreenInformation() {
// print('Device width dp:${1.sw}dp');
// print('Device height dp:${1.sh}dp');
// print('Device pixel density:${ScreenUtil().pixelRatio}');
// print('Bottom safe zone distance dp:${ScreenUtil().bottomBarHeight}dp');
// print('Status bar height dp:${ScreenUtil().statusBarHeight}dp');
// print('The ratio of actual width to UI design:${ScreenUtil().scaleWidth}');
// print(
// 'The ratio of actual height to UI design:${ScreenUtil().scaleHeight}');
// print('System font scaling:${ScreenUtil().textScaleFactor}');
// print('0.5 times the screen width:${0.5.sw}dp');
// print('0.5 times the screen height:${0.5.sh}dp');
// }
void printScreenInformation() {
print('ScreenUtil().screenWidth = ${ScreenUtil().screenWidth}');
print('设备宽度:${1.sw}dp');
print('"1.w" = ${1.w}');
print('"1.sw" = ${1.sw}');
print('设备高度:${1.sh}dp');
print('设备的像素密度:${ScreenUtil().pixelRatio}');
print('底部安全区距离:${ScreenUtil().bottomBarHeight}dp');
print('状态栏高度:${ScreenUtil().statusBarHeight}dp');
print('实际宽度的dp与设计稿px的比例:${ScreenUtil().scaleWidth}');
print('实际高度的dp与设计稿px的比例:${ScreenUtil().scaleHeight}');
print('宽度和字体相对于设计稿放大的比例:${ScreenUtil().scaleWidth * ScreenUtil().pixelRatio}');
print('高度相对于设计稿放大的比例:${ScreenUtil().scaleHeight * ScreenUtil().pixelRatio}');
print('系统的字体缩放比例:${ScreenUtil().textScaleFactor}');
print('屏幕宽度的0.5:${0.5.sw}dp');
print('屏幕高度的0.5:${0.5.sh}dp');
}
//3、得到违章图片说明信息组件
Widget getWztpSmxx() {
return Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(390),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
//违章信息组件1:车牌号码、车牌颜色
getWzxxPart1(),
//违章信息组件2:抓拍时间组件
getWzxxText('抓拍时间:' + widget.mapZpjl['zpsj']),
//违章信息组件3:车牌类型 + 黑度
getWzxxPart3(),
//违章信息组件4:抓拍地点(简称)
getWzxxText('抓拍地点:' + getDwmc(widget.mapZpjl['dwip']) + ' (简称)'),
//违章信息组件5:抓拍地点
getWzxxText('抓拍地点:' + widget.mapZpjl['dwms']),
],
),
);
}
// I/flutter (22989): ScreenUtil().screenWidth = 360.0
// I/flutter (22989): 设备宽度:360.0dp
// I/flutter (22989): "1.w" = 0.3333333333333333
// I/flutter (22989): "1.sw" = 360.0
// I/flutter (22989): 设备高度:640.0dp
// I/flutter (22989): 设备的像素密度:3.0
// I/flutter (22989): 底部安全区距离:0.0dp
// I/flutter (22989): 状态栏高度:24.0dp
// I/flutter (22989): 实际宽度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 实际高度的dp与设计稿px的比例:0.3333333333333333
// I/flutter (22989): 宽度和字体相对于设计稿放大的比例:1.0
// I/flutter (22989): 高度相对于设计稿放大的比例:1.0
// I/flutter (22989): 系统的字体缩放比例:1.0
// I/flutter (22989): 屏幕宽度的0.5:180.0dp
// I/flutter (22989): 屏幕高度的0.5:320.0dp
//3、得到违章信息组件1:车牌号码、车牌颜色
//车牌颜色Map cpysMap = {
// '蓝色': cpysItem(
// cpysText: '蓝色',
// cpysBackground: Colors.blue,
// cpysFont: Colors.white,
// cpysBorder: Colors.orange),
// }
Widget getWzxxPart1() {
//printScreenInformation();
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
getTitleText('车牌号码:'),
getBoderText(widget.mapZpjl[mapName['plate_id']].toString(),
width: ScreenUtil().setWidth(1022 / 3.2)),
Expanded(child: SizedBox.shrink()),
getTitleText('颜色:'),
getBoderText(widget.mapZpjl[mapName['plate_color']],
width: ScreenUtil().setWidth(1022 / 4.8)),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
],
);
}
Widget getTitleRichText(String text1, {String text2 = '', double fontSize = 16}) {
return RichText(
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
text: TextSpan(
text: text1,
style: TextStyle(fontSize: fontSize, color: Colors.black),
children: [
TextSpan(
text: text2,
style: TextStyle(fontSize: fontSize, color: Colors.blue, fontWeight: FontWeight.w500),
),
],
),
);
}
Widget getTitleText(String text, {double fontSize = 16}) {
return Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis);
}
Widget getTrailText(String text, {double fontSize = 16, double off = 0}) {
return Container(
width: _screenWidth - _widthLeft - off - (2 * ScreenUtil().setWidth(_marginLeft)),
child: Text(text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
);
}
Widget getBoderText(String text, {double width = 40}) {
cpysItem _cpysItem = cpysMap[widget.mapZpjl[mapName['plate_color']]];
return Container(
//color: _cpysItem.cpysBackground,
alignment: Alignment(0, -1),
width: width,
decoration: BoxDecoration(
border: Border.all(color: _cpysItem.cpysBorder, width: 2),
color: _cpysItem.cpysBackground,
borderRadius: BorderRadius.circular(3),
),
child: Padding(
padding: EdgeInsets.only(bottom: 3),
child: Text(text,
style: TextStyle(fontSize: _fontSize, color: _cpysItem.cpysFont),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
),
);
}
//I/flutter (17555): mapZpjl = {
// id: 1222, plate_id: 川Q736X2, plate_color: 蓝色, zpsj: 1612857077, yjxx_id: 1399, workflow: 999,
// video_url: video/9_6063_20210209_155117_川Q736X2.mp4,
// pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/9d2f45fd24b41f2b94abe42b30970d75.jpg,
// clfl: 集装箱卡车, dwip: 172.16.3.9, dwms: 宜长路出城方向, lgmzs: 3, jczxd: 994, sfhy: 黑烟车
// }
Widget getIcon(IconData _iconData) {
return Container(
width: _iconSize - 2,
height: _iconSize,
child: Padding(
padding: EdgeInsets.only(top: 2),
child: Icon(_iconData, size: _iconSize, color: _iconColor),
),
);
}
Widget getWzxxText(String _text, {double fontSize = 16}) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022) - ScreenUtil().setWidth(_marginLeft),
child: Text(_text,
style: TextStyle(fontSize: fontSize),
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis),
),
],
);
}
Widget getWzxxPart3() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
//width: ScreenUtil().setWidth(1022) - ScreenUtil().setWidth(_marginLeft),
child: getTitleText('车牌类型:' + widget.mapZpjl['cplx']),
),
Expanded(child: SizedBox.shrink()),
//getTitleText('黑度: ${widget.mapZpjl['lgmzs']}'),
getTitleRichText('黑度:', text2: '${widget.mapZpjl['lgmzs']} '),
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
],
);
}
Widget getText(String text, {Color color}) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022 - 2 * _marginLeft),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text(text,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: color))
],
),
),
],
);
}
Widget getText2(String text1, String text2, String text3, {Color color}) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022 - 2 * _marginLeft),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text(text1, textAlign: TextAlign.left),
Text(text2,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: color, fontWeight: FontWeight.w500)),
Text(text3, textAlign: TextAlign.left),
],
),
),
],
);
}
//5、得到黑烟初审'hycsInfo'、或者黑烟'hyfhInfo'複核信息组件
//style: TextStyle(fontSize: _fontSize),
Widget getHyshInfo(String _hyshInfo) {
String _hyshLx = (_hyshInfo == 'hycsInfo' ? '初审' : '复审'); //黑烟审核类型
String _hyshYh = (_hyshInfo == 'hycsInfo' ? 'cs_username' : 'fs_username'); //黑烟审核用户
String _hyshSj = (_hyshInfo == 'hycsInfo' ? 'cs_time' : 'fs_time'); //黑烟审核时间
String _hyshJg = (_hyshInfo == 'hycsInfo' ? 'cs_tile' : 'fs_tile'); //黑烟审核结果
String _hyshYj = (_hyshInfo == 'hycsInfo' ? 'cs_shuoming' : 'fs_shuoming'); //黑烟审核意见
double _height = _hyshInfo == 'hyfhInfo' && widget.hyshlx == 'tsjj' ? 315 : 265;
return Column(
children: [
Container(
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(_height),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(
Radius.circular(12),
),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Container(
alignment: Alignment(-1, 0),
width: ScreenUtil().setWidth(1022 - 2 * _marginLeft),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Text('${_hyshLx}结果:' + widget.mapZpjl[_hyshJg],
textAlign: TextAlign.left, overflow: TextOverflow.ellipsis),
SizedBox(width: ScreenUtil().setWidth(20)),
Container(
width: my_iconSize,
height: my_iconSize,
decoration: widget.mapZpjl[_hyshJg] == ''
? null
: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
image: AssetImage(widget.mapZpjl[_hyshJg] == "黑烟车"
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
alignment: Alignment.center,
//child:
),
],
),
),
],
),
getText('${_hyshLx}意见:' + widget.mapZpjl[_hyshYj]),
getText('${_hyshLx}用户:' + widget.mapZpjl[_hyshYh]),
getText('${_hyshLx}时间:' + widget.mapZpjl[_hyshSj]),
_hyshInfo == 'hyfhInfo' && widget.hyshlx == 'tsjj'
? (getText2('推送状态:', widget.tsztText, ' (${getDate(widget.mapZpjl['ts_time'])})',
color:
widget.tsztText.indexOf('成功') >= 0 ? Colors.blueAccent : Colors.black26))
: SizedBox.shrink(),
],
),
),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
],
);
}
//9、得到推送交警状态信息组件7:推送状态
// tszt 整型 推送状态:0-未推送 | 1-推送失败 | 3-推送成功
//_mapTsjjGetTsStatus['tszt']
Widget getWzxxPart7() {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: ScreenUtil().setWidth(_marginLeft)),
Container(
alignment: Alignment(-1, 0),
width: _screenWidth - ScreenUtil().setWidth(_marginLeft),
child: getTitleText('推送状态:' + mapTsztText[_mapTsjjGetTsStatus['tszt']]),
),
],
);
}
//10、得到推送交警确认组件
Widget getTsjjQr() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
getBtnSizeX(
text: "返回",
onPressedFun: () async {
Navigator.pop(context);
},
width: 90.0),
],
);
}
bool showMoreWidget = false;
@override
Widget build(BuildContext context) {
return Scaffold(
//resizeToAvoidBottomPadding: false,
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
//设置title的左边距
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
//mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: showMoreWidget
? null
: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(widget.text + '记录' + widget.num,
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 30),
],
),
),
),
),
body: null == imageWztp
// 显示加载中的圈圈
? getMoreWidget(color: Colors.black38, size: 20.0, strokeWidth: 2.0)
: Stack(
children: [
//SizedBox.shrink() 创建父类允许最小尺寸的约束Box
showMoreWidget
? Align(
alignment: Alignment(0, 0.8),
child: Container(
height: 200,
width: 200,
child: getMoreWidget2(
text: '加载中...',
color: Colors.red,
size: 40.0,
strokeWidth: 3.0), //显示加载中的圈圈,
),
)
: SizedBox.shrink(),
KeyboardAvoider(
autoScroll: true,
child: Container(
color: Color.fromRGBO(244, 244, 244, 1),
child: Column(
children: <Widget>[
//1、得到格林曼黑度标准和视频播放按钮组件
getHdAndPlay(),
//2、得到违章图片组件
imageWztp,
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//3、得到违章图片说明信息组件
getWztpSmxx(),
SizedBox(height: ScreenUtil().setHeight(_marginVer)),
//7、得到黑烟初审信息组件
widget.hyshlx == 'hycs' ||
widget.hyshlx == 'hyfh' ||
widget.hyshlx == 'tsjj'
? getHyshInfo('hycsInfo')
: SizedBox.shrink(),
//8、得到黑烟复审信息组件
widget.hyshlx == 'hyfh' || widget.hyshlx == 'tsjj'
? getHyshInfo('hyfhInfo')
: SizedBox.shrink(),
SizedBox(height: widget.hyshlx == 'tsjj' ? 0 : 15),
//9、得到推送交警确认组件
getTsjjQr(),
//SizedBox(height: 10),
],
),
),
),
widget.hyshlx == 'tsjj'
? Positioned(
//alignment: Alignment(0.9, 0.35),
//alignment: Alignment(0.8, 0.45),
right: ScreenUtil().setWidth(50),
top: ScreenUtil().setHeight(1423),
child: Container(
//alignment: Alignment(0.5, -0.5),
width: _stampSize,
height: _stampSize,
//color: Colors.black12,
decoration: BoxDecoration(
//color: Colors.white,
image: DecorationImage(
//image: AssetImage("assets/images/jkzx_stamp.png"), fit: BoxFit.contain),
image: AssetImage(widget.mapZpjl['fs_tile'] == '黑烟车'
? "assets/images/hyc.png"
: "assets/images/fhyc.png"),
fit: BoxFit.contain),
),
//child:
),
)
: SizedBox.shrink(),
],
),
);
}
Widget getBtnSizeX({@required text, width = 70.0, height = 35.0, onPressedFun}) {
return Container(
color: Colors.white12, //onPressedFun为null时无效
width: width,
height: height,
child: RaisedButton(
padding: EdgeInsets.all(0),
textColor: Colors.black,
child: Text(text),
onPressed: onPressedFun,
),
);
}
}
+629
View File
@@ -0,0 +1,629 @@
import 'package:fl_chart/fl_chart.dart';
//import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
class ZptjBarChart extends StatefulWidget {
ZptjBarChart({this.statisType, this.data_ok = false, Key key}) : super(key: key);
String statisType; //统计类型
bool data_ok; //listZptjStatis 中的数据是否准备好
@override
State<StatefulWidget> createState() => ZptjBarChartState();
}
class ZptjBarChartState extends State<ZptjBarChart> {
static const Color red = const Color(0xffff5182);
static const Color blue = const Color(0xff0000ff);
static const Color leftBarColor = const Color(0xffff5182);
static const Color rightBarColor = const Color(0xff0000ff);
static const Color bottomBarColor = const Color(0xff939393);
static const Color gridColor = const Color(0xffe7e8ec);
static const double width = 7;
String _textBottom1;
String _textBottom2;
String _textTop1;
String _textTop2;
int _rate = 10; // today 字段放大倍率
int _rateCoord = 10000; // 坐标压缩倍率
int _interval = 20; // 坐标间隔
int _maxY = -1;
List<BarChartGroupData> _listBarData = [];
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void initState() {
super.initState();
getDataNew().then((value) {
_listBarData = value;
try_setState();
});
// ///获取点位信息数据
// if (!widget.data_ok) {
// //listZptjStatis 中的数据未准备好
// listZptjStatis.clear(); //最后需要显示的数据
// }
//
// if (listZptjStatis.isEmpty) {
// if (listDwinfoGetList2.isEmpty) {
// //若没有读取了点位数据,便需要先读取
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// });
// } else {
// //若已经读取了点位数据,便直接使用
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// }
// } else {
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// }
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text(mapStatisType[widget.statisType]['text']),
// centerTitle: true,
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(mapStatisType[widget.statisType]['text'],
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
alignment: Alignment(0, -0.85),
child: AspectRatio(
aspectRatio: 0.94, //宽高比
child: Card(
elevation: 4, //阴影高度
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
color: Colors.white,
child: Container(
padding: const EdgeInsets.only(top: 20),
child: (listAllStatisData.isEmpty || _listBarData.isEmpty)
? getMoreWidget(color: Colors.black38)
: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textTop1, style: TextStyle(color: leftBarColor, fontSize: 12)),
Expanded(
child: Text(''),
),
Text(_textTop2, style: TextStyle(color: rightBarColor, fontSize: 12)),
SizedBox(width: 3),
],
),
SizedBox(
height: 10,
),
BarChart(
BarChartData(
maxY: _maxY.toDouble() * 1.1,
groupsSpace: 6,
alignment: BarChartAlignment.spaceEvenly,
barTouchData: BarTouchData(
enabled: false,
),
//坐标数据
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
rotateAngle: 45,
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: bottomBarColor, fontSize: 10),
margin: 10,
getTitles: (double value) {
int i = value.toInt() - 1;
return '${listAllStatisData[i]['id']}. ${listAllStatisData[i]['dwmc']}';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: leftBarColor, fontSize: 10),
margin: 4, //边距
getTitles: (double value) {
value = value / _rateCoord; //坐标压缩别率
if (value.toInt() % _interval == 0) {
return '${(value / _rate).toInt()}'; //将左侧坐标放大 _rate 倍
} else {
return '';
}
},
),
rightTitles: SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: rightBarColor, fontSize: 10),
margin: 4,
getTitles: (double value) {
value = value / _rateCoord; //坐标压缩别率
if (value.toInt() % _interval == 0) {
return '${value.toInt()}';
} else {
return '';
}
},
),
),
//栅格线
gridData: FlGridData(
show: true,
checkToShowHorizontalLine: (value) => value % _rate == 0,
getDrawingHorizontalLine: (value) => FlLine(
color: gridColor,
strokeWidth: 1,
),
),
//边线
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: gridColor,
width: 2,
),
left: BorderSide(
color: leftBarColor,
width: 2,
),
right: BorderSide(
color: rightBarColor,
width: 2,
),
top: BorderSide(
color: Colors.transparent,
),
),
),
//图标数据
barGroups: _listBarData,
//barGroups: showingBarGroups,
),
),
SizedBox(height: 30),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textBottom1,
style: TextStyle(color: leftBarColor, fontSize: 12)),
Expanded(
child: Container(
alignment: Alignment.center,
child: Text('点位编号',
style: TextStyle(color: bottomBarColor, fontSize: 12)),
),
),
Text(_textBottom2,
style: TextStyle(color: rightBarColor, fontSize: 12)),
SizedBox(width: 3),
],
),
]),
),
),
),
),
);
}
List<int> bar_getAllSumNew(String field) {
int items = 0;
int sum = 0;
for (var item in listAllStatisData) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
Future<List<BarChartGroupData>> getDataNew() async {
String _field1 = '';
String _field2 = '';
_maxY = -1;
int len = listAllStatisData.length;
List<BarChartGroupData> listBarData = [];
switch (widget.statisType) {
case 'zptj':
_field1 = 'zp_today';
_field2 = 'zp_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1]}'; // 'all' 字段没有记录详情,所以用bar_getAllSumCll()
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
case 'sh_hyc_tj':
_field1 = 'hyc_all';
_field2 = 'send_all';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩倍率
_interval = 2; // 坐标间隔
_textBottom1 = '已审核 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '已推送 ${bar_getAllSumNew(_field2)[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
/*
listAllStatisData =
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 53,
"zp_today": 1,
"sends": 1,
"send_all": 34,
"csnum": 1,
"fsnum": 1,
"cll_today": 23200,
"cll_all": 3242513
},
...
]
*/
case 'clltj':
_field1 = 'cll_today';
_field2 = 'cll_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1] ~/ _rateCoord} 万辆';
_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1] ~/ _rateCoord} 万辆';
_textTop1 = '今日(万辆)';
_textTop2 = '(万辆)合计';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
_maxY = listAllStatisData[i][_field2] > _maxY ? listAllStatisData[i][_field2] : _maxY;
}
break;
default:
break;
}
return listBarData;
}
Future<List<BarChartGroupData>> getData() async {
String _field1 = '';
String _field2 = '';
_maxY = -1;
int len = listZptjStatis.length;
List<BarChartGroupData> listBarData = [];
switch (widget.statisType) {
case 'zptj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSum('today')[1]}';
_textBottom2 = '总共 ${bar_getAllSumCll('all')[1]}'; // 'all' 字段没有记录详情,所以用bar_getAllSumCll()
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1]["total"] * _rate).toDouble(),
listZptjStatis[i][_field2].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1]["total"] * _rate > _maxY
? listZptjStatis[i][_field1]["total"] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
break;
case 'sh_hyc_tj':
_field1 = 'total';
_field2 = 'sends';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 2; // 坐标间隔
_textBottom1 =
'已审核 ${bar_getAllSumCll('total')[1]}'; // 'total' 字段没有记录详情,所以用bar_getAllSumCll()
_textBottom2 = '已推送 ${bar_getAllSum('sends')[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1] * _rate).toDouble(),
listZptjStatis[i][_field2]["total"].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1] * _rate > _maxY
? listZptjStatis[i][_field1] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2]["total"] > _maxY
? listZptjStatis[i][_field2]["total"]
: _maxY;
}
break;
case 'clltj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumCll('today')[1] ~/ _rateCoord} 万辆';
_textBottom2 = '总共 ${bar_getAllSumCll('all')[1] ~/ _rateCoord} 万辆';
_textTop1 = '今日(万辆)';
_textTop2 = '(万辆)合计';
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listZptjStatis[i]['dwbh'],
(listZptjStatis[i][_field1] * _rate).toDouble(),
listZptjStatis[i][_field2].toDouble()),
);
//得到最大值
_maxY = listZptjStatis[i][_field1] * _rate > _maxY
? listZptjStatis[i][_field1] * _rate
: _maxY;
_maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
break;
default:
break;
}
return listBarData;
}
BarChartGroupData makeGroupData(int x, double y1, double y2) {
return BarChartGroupData(barsSpace: 0, x: x, barRods: [
BarChartRodData(
y: y1,
colors: [leftBarColor],
width: width,
borderRadius: const BorderRadius.all(Radius.zero),
),
BarChartRodData(
y: y2,
colors: [rightBarColor],
width: width,
borderRadius: const BorderRadius.all(Radius.zero),
),
]);
}
//获取已审核黑烟车统计数据:App.Car_Statis.GetStaHyc
//{
// "ret": 200,
// "data": {
// "total": 40,
// "sends": {
// "total": 0,
// "data": []
// },
// "csnum": {
// "total": 0,
// "data": []
// },
// "fsnum": {
// "total": 0,
// "data": []
// }
// },
// "msg": ""
// }
//获取抓拍统计数据:App.Car_Statis.GetStaYjxx
//{
// "ret": 200,
// "data": {
// "today": {
// "total": 0,
// "data": []
// },
// "all": 40
// },
// "msg": ""
// }
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:抓拍统计的'today'、all;审核统计的"total"、"sends";
List<int> bar_getAllSum(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field]["total"] > 0) {
items++;
sum += item[field]["total"];
}
}
return [items, sum];
}
//获取车流量统计数据:App.Car_Statis.GetStaCll
//{
// "ret": 200,
// "data": {
// "today": 7010,
// "all": 1640350
// },
// "msg": ""
//}
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:车流量统计的'today'、all
List<int> bar_getAllSumCll(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
}
@@ -0,0 +1,508 @@
import 'package:fl_chart/fl_chart.dart';
//import 'package:flustars/flustars.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/components/dioFun.dart';
import 'package:hyzp_ybqx/components/hyxx_data_handle.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
class ZptjBarChartOne extends StatefulWidget {
ZptjBarChartOne({this.statisType, this.data_ok = false, Key key}) : super(key: key);
String statisType; //统计类型
bool data_ok; //listZptjStatis 中的数据是否准备好
@override
State<StatefulWidget> createState() => ZptjBarChartOneState();
}
class ZptjBarChartOneState extends State<ZptjBarChartOne> {
static const Color red = const Color(0xffff5182);
static const Color blue = const Color(0xff0000ff);
static const Color leftBarColor = const Color(0xffff5182);
static const Color rightBarColor = const Color(0xff0000ff);
static const Color bottomBarColor = const Color(0xff939393);
static const Color gridColor = const Color(0xffe7e8ec);
static const double width = 7;
String _textBottom1;
String _textBottom2;
String _textTop1;
String _textTop2;
int _rate = 10; // today 字段放大倍率
int _rateCoord = 10000; // 坐标压缩倍率
int _interval = 20; // 坐标间隔
int _maxY = -1;
List<BarChartGroupData> _listBarData = [];
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void initState() {
super.initState();
print('ZptjBarChartOne');
getDataNew().then((value) {
_listBarData = value;
try_setState();
});
// ///获取点位信息数据
// if (!widget.data_ok) {
// //listZptjStatis 中的数据未准备好
// listZptjStatis.clear(); //最后需要显示的数据
// }
//
// if (listZptjStatis.isEmpty) {
// if (listDwinfoGetList2.isEmpty) {
// //若没有读取了点位数据,便需要先读取
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// });
// } else {
// //若已经读取了点位数据,便直接使用
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// //按 sortField 升序排序
// listZptjStatis.sort((a, b) => (a['dwbh']).compareTo(b['dwbh']));
//
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// });
// }
// } else {
// getData().then((value) {
// _listBarData = value;
// try_setState();
// });
// }
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text(mapStatisType[widget.statisType]['text']),
// centerTitle: true,
// ),
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)),
// 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight),
//留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(mapStatisType[widget.statisType]['text'],
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 50),
],
),
),
),
),
body: Container(
alignment: Alignment(0, -0.85),
child: AspectRatio(
aspectRatio: 0.94, //宽高比
child: Card(
elevation: 4, //阴影高度
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)),
color: Colors.white,
child: Container(
padding: const EdgeInsets.only(top: 20),
child: (listAllStatisData.isEmpty || _listBarData.isEmpty)
? getMoreWidget(color: Colors.black38)
: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
mainAxisAlignment: MainAxisAlignment.start,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textTop1, style: TextStyle(color: leftBarColor, fontSize: 12)),
Expanded(
child: Text(''),
),
Text(_textTop2, style: TextStyle(color: rightBarColor, fontSize: 12)),
SizedBox(width: 3),
],
),
SizedBox(
height: 10,
),
BarChart(
BarChartData(
maxY: _maxY.toDouble() * 1.1,
groupsSpace: 6,
alignment: BarChartAlignment.spaceEvenly,
barTouchData: BarTouchData(
enabled: false,
),
//坐标数据
titlesData: FlTitlesData(
show: true,
bottomTitles: SideTitles(
rotateAngle: 45,
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: bottomBarColor, fontSize: 10),
margin: 10,
getTitles: (double value) {
int i = value.toInt() - 1;
return '${listAllStatisData[i]['id']}. ${listAllStatisData[i]['dwmc']}';
},
),
leftTitles: SideTitles(
showTitles: true,
getTextStyles: (value) =>
const TextStyle(color: leftBarColor, fontSize: 10),
margin: 4, //边距
getTitles: (double value) {
//value = value / 1000; //坐标压缩别率
if (value.toInt() % 20000 == 0) {
return '${value / 100000}'; //将左侧坐标放大 _rate 倍
} else {
return '';
}
// if (value.toInt() % _interval == 0) {
// return '${(value / _rate).toInt()}'; //将左侧坐标放大 _rate 倍
// } else {
// return '';
// }
},
),
rightTitles: SideTitles(
showTitles: true,
// getTextStyles: (value) => const TextStyle(color: rightBarColor, fontSize: 10),
getTextStyles: (value) =>
const TextStyle(color: leftBarColor, fontSize: 10),
margin: 4,
getTitles: (double value) {
if (value.toInt() % 20000 == 0) {
return '${value / 100000}'; //将左侧坐标放大 _rate 倍
//return '';
} else {
return '';
}
},
),
),
//栅格线
gridData: FlGridData(
show: true,
checkToShowHorizontalLine: (value) => value % _rate == 0,
getDrawingHorizontalLine: (value) => FlLine(
color: gridColor,
strokeWidth: 1,
),
),
//边线
borderData: FlBorderData(
show: true,
border: const Border(
bottom: BorderSide(
color: gridColor,
width: 2,
),
left: BorderSide(
color: leftBarColor,
width: 2,
),
right: BorderSide(
// color: rightBarColor,
color: leftBarColor,
width: 2,
),
top: BorderSide(
color: Colors.transparent,
),
),
),
//图表数据
barGroups: _listBarData,
//barGroups: showingBarGroups,
),
),
SizedBox(height: 30),
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
SizedBox(width: 3),
Text(_textBottom1,
style: TextStyle(color: leftBarColor, fontSize: 12)),
SizedBox(width: 60),
Text('点位编号', style: TextStyle(color: bottomBarColor, fontSize: 12)),
// Text(_textBottom2,
// style: TextStyle(color: rightBarColor, fontSize: 12)),
//SizedBox(width: 73),
],
),
]),
),
),
),
),
);
}
List<int> bar_getAllSumNew(String field) {
int items = 0;
int sum = 0;
for (var item in listAllStatisData) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
Future<List<BarChartGroupData>> getDataNew() async {
String _field1 = '';
String _field2 = '';
switch (widget.statisType) {
case 'zptj':
_field1 = 'zp_today';
_field2 = 'zp_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1]}'; // 'all' 字段没有记录详情,所以用bar_getAllSumCll()
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
break;
case 'sh_hyc_tj':
_field1 = 'hyc_all';
_field2 = 'send_all';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩倍率
_interval = 2; // 坐标间隔
_textBottom1 = '已审核 ${bar_getAllSumNew(_field1)[1]}';
_textBottom2 = '已推送 ${bar_getAllSumNew(_field2)[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
break;
/*
listAllStatisData =
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 53,
"zp_today": 1,
"sends": 1,
"send_all": 34,
"csnum": 1,
"fsnum": 1,
"cll_today": 23200,
"cll_all": 3242513
},
...
]
*/
case 'clltj':
_field1 = 'cll_today';
_field2 = 'cll_all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 5; // 坐标间隔
_textBottom1 = '今日合计 ${bar_getAllSumNew(_field1)[1] ~/ _rateCoord} 万辆';
//_textBottom2 = '总共 ${bar_getAllSumNew(_field2)[1] ~/ _rateCoord} 万辆';
_textBottom2 = '';
_textTop1 = '今日(万辆)';
//_textTop2 = '(万辆)合计';
_textTop2 = '';
break;
default:
break;
}
_maxY = -1;
int len = listAllStatisData.length;
List<BarChartGroupData> listBarData = [];
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(
listAllStatisData[i]['id'],
(listAllStatisData[i][_field1] * _rate).toDouble(),
listAllStatisData[i][_field2].toDouble()),
);
//得到最大值,只显示今日车流量
_maxY = listAllStatisData[i][_field1] * _rate > _maxY
? listAllStatisData[i][_field1] * _rate
: _maxY;
// _maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
return listBarData;
}
Future<List<BarChartGroupData>> getData() async {
String _field1 = '';
String _field2 = '';
switch (widget.statisType) {
case 'zptj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 20; // 坐标间隔
_textBottom1 = '今日合计 ${getAllSum('today')[1]}';
_textBottom2 = '总共 ${getAllSum('all')[1]}';
_textTop1 = '今日(次)';
_textTop2 = '(次)合计';
_rateCoord = 1;
break;
case 'sh_hyc_tj':
_field1 = 'total';
_field2 = 'sends';
_rate = 1; // today 字段放大倍率
_rateCoord = 1; //坐标压缩别率
_interval = 2; // 坐标间隔
_textBottom1 = '今日审核 ${getAllSum('total')[1]}';
_textBottom2 = '今日推送 ${getAllSum('sends')[1]}';
_textTop1 = '审核(次)';
_textTop2 = '(次)推送';
break;
case 'clltj':
_field1 = 'today';
_field2 = 'all';
_rate = 10; // today 字段放大倍率
_rateCoord = 10000; //坐标压缩别率
_interval = 5; // 坐标间隔
_textBottom1 = '今日合计 ${getAllSum('today')[1] ~/ (_rateCoord)} 万辆';
//_textBottom2 = '总共 ${getAllSum('all')[1] ~/ _rateCoord} 千辆';
_textBottom2 = '';
_textTop1 = '今日(万辆)';
//_textTop2 = '(千辆)合计';
_textTop2 = '';
break;
default:
break;
}
_maxY = -1;
int len = listZptjStatis.length;
List<BarChartGroupData> listBarData = [];
for (int i = 0; i < len; i++) {
//将 today 字段放大 _rate 倍
listBarData.add(
makeGroupData(listZptjStatis[i]['dwbh'], (listZptjStatis[i][_field1] * _rate).toDouble(),
listZptjStatis[i][_field2].toDouble()),
);
//得到最大值,只显示今日车流量
_maxY =
listZptjStatis[i][_field1] * _rate > _maxY ? listZptjStatis[i][_field1] * _rate : _maxY;
// _maxY = listZptjStatis[i][_field2] > _maxY ? listZptjStatis[i][_field2] : _maxY;
}
return listBarData;
}
BarChartGroupData makeGroupData(int x, double y1, double y2) {
return BarChartGroupData(barsSpace: 0, x: x, barRods: [
BarChartRodData(
y: y1,
colors: [leftBarColor],
width: width,
borderRadius: const BorderRadius.all(Radius.zero),
),
// BarChartRodData(
// y: y2,
// colors: [rightBarColor],
// width: width,
// borderRadius: const BorderRadius.all(Radius.zero),
// ),
]);
}
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:抓拍统计和车流量统计的'today'、all;审核统计的"total"、"sends";
List<int> getAllSum(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
}
+835
View File
@@ -0,0 +1,835 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/save_data_to_file.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/zptj_bar_chart.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/zptj_bar_chart_one.dart';
import '../../../components/commonFun.dart';
import '../../../components/hyxx_data_handle.dart';
import 'tj_data.dart';
//zptj 是本项目中“抓拍统计”的统一缩写
//sh_hyc_tj 是本项目中“审核黑烟车统计”的统一缩写
//clltj 是本项目中“车流量统计”的统一缩写
class ZptjPage extends StatefulWidget {
//mapStatisType 为统计数据类型数据结构。用于在同一套代码中,处理相似类型的多种统计数据
//statisType 为统计类型。mapStatisType[statisType] 为各种相似类型的设置数据
ZptjPage({@required this.statisType, Key key}) : super(key: key);
String statisType;
_ZptjPageState createState() => _ZptjPageState();
}
class _ZptjPageState extends State<ZptjPage> {
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
void dispose() {
super.dispose();
}
@override
void initState() {
// ///获取点位信息数据
// listZptjStatis.clear(); //最后需要显示的数据
//
// if (listDwinfoGetList2.isEmpty) {
// //若没有读取了点位数据,便需要先读取
// getThePageList(theHyshlx: 'dwxx').then((value) {
// listDwinfoGetList2 = value;
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// _listSort(sortField: 'dwbh');
// });
// });
// } else {
// //若已经读取了点位数据,便直接使用
// print('listDwinfoGetList2 = \n$listDwinfoGetList2');
// getZptjStatis(widget.statisType).then((value) {
// _listSort(sortField: 'dwbh');
// });
// }
super.initState();
}
///获取点位信息数据
// List listDwinfoGetList2 = [
// {
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆"
// },
// ];
//listZptjStatis = [
// {today: 832, all: 4479, dwip: 172.16.3.1},
// {today: 0, all: 185, dwip: 172.16.3.2},
// {today: 0, all: 131, dwip: 172.16.3.3},
// {today: 0, all: 72, dwip: 172.16.3.4},
// {today: 0, all: 30, dwip: 172.16.3.5},
// {today: 0, all: 26, dwip: 172.16.3.6},
// {today: 0, all: 0, dwip: 172.16.3.7},
// {today: 0, all: 135, dwip: 172.16.3.8},
// {today: 0, all: 65, dwip: 172.16.3.9},
// {today: 0, all: 36, dwip: 172.16.3.10},
// {today: 0, all: 44, dwip: 172.16.3.11},
// {today: 0, all: 76, dwip: 172.16.3.12},
// {today: 0, all: 83, dwip: 172.16.3.13}
//]
Widget _getListTile(BuildContext context, int indexRecord, {double width = 520}) {
switch (widget.statisType) {
case 'zptj':
return _getZptjListTile(context, indexRecord, 520);
break;
case 'clltj':
return _getClltjListTile(context, indexRecord, 520);
break;
case 'sh_hyc_tj':
return _getSh_hyc_tjListTile(context, indexRecord, 510);
break;
default:
return Container();
break;
}
}
//抓拍统计数据
//{
// "today": 0,
// "all": 72
// "dwbh": 1,
// "dwmc": "江北振兴大道",
// "dwip": "172.16.3.1"
//}
Widget _getSh_hyc_tjListTile(BuildContext context, int indexRecord, double width) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: getDwmcField(indexRecord, 40),
// subtitle:
// Text('今日:${listZptjStatis[indexRecord]['today']}', style: TextStyle(fontSize: 10)),
trailing: Container(
width: ScreenUtil().setWidth(width),
child: Row(
children: [
getText(
text: listAllStatisData[indexRecord]['hyc_all'].toString(),
width: 260,
fontSize: 16),
getText(
text: listAllStatisData[indexRecord]['send_all'].toString(),
width: 240,
fontSize: 16),
],
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {},
),
Divider(height: 1.0),
],
);
}
Widget getText({String text = '', double width = 100, double fontSize = 16}) {
return SizedBox(
width: ScreenUtil().setWidth(width),
child: Text(
text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
//textAlign: TextAlign.right,
style: TextStyle(fontSize: fontSize),
),
);
}
///获取点位信息数据
// List listDwinfoGetList2 = [
// {
// "id": 1,
// "dwip": "172.16.3.1",
// "dwmc": "江北振兴大道",
// "dwbh": 1,
// "dwinfo": "江北振兴大道入城方向",
// "dwzb": "104.607091|28.807061",
// "dwms": "江北振兴大道入城方向,识别孜岩、红坝路入城排放黑烟车辆"
// },
// ];
Widget getDwmcField(int indexRecord, double width) {
return SizedBox(
width: ScreenUtil().setWidth(width),
child: Text(
'${listAllStatisData[indexRecord]["id"].toString()}. ${listAllStatisData[indexRecord]["dwmc"]}',
style: TextStyle(fontSize: 16),
),
);
}
/*
listAllStatisData =
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 53,
"zp_today": 1,
"sends": 1,
"send_all": 34,
"csnum": 1,
"fsnum": 1,
"cll_today": 23200,
"cll_all": 3242513
},
...
]
*/
Widget _getZptjListTile(BuildContext context, int indexRecord, double width) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: getDwmcField(indexRecord, 40),
// subtitle:
// Text('今日:${listAllStatisData[indexRecord]['today']}', style: TextStyle(fontSize: 10)),
trailing: Container(
width: ScreenUtil().setWidth(width),
child: Row(
children: [
getText(
text: listAllStatisData[indexRecord]['zp_today'].toString(),
width: 260,
fontSize: 16),
getText(
text: listAllStatisData[indexRecord]['zp_all'].toString(),
width: 260,
fontSize: 16),
],
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {},
),
Divider(height: 1.0),
],
);
}
Widget _getClltjListTile(BuildContext context, int indexRecord, double width) {
return Column(
children: <Widget>[
ListTile(
//leading: new Icon(Icons.phone),
title: getDwmcField(indexRecord, 40),
// subtitle:
// Text('今日:${listAllStatisData[indexRecord]['today']}', style: TextStyle(fontSize: 10)),
trailing: Container(
width: ScreenUtil().setWidth(width),
child: Row(
children: [
// getText(
// text: listAllStatisData[indexRecord]['today'].toString(),
// width: 260,
// fontSize: 16),
// getText(
// text: (listAllStatisData[indexRecord]['all'] / 10000).toString(),
// width: 260,
// fontSize: 16),
getText(text: '', width: 260, fontSize: 16),
getText(
text: listAllStatisData[indexRecord]['cll_today'].toString(),
width: 260,
fontSize: 16),
],
),
),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: () async {},
),
Divider(height: 1.0),
],
);
}
bool isLoading = false; //正在处理下载数据、跳转到首项、跳转到尾项等操作
//Map<String, String> mapTjDataText = {
// "dwip": '点位IP',
// "today": '今日',
// "all": '总共',
// "total": '总共2',
// "sends": '推送'
// };
//抓拍统计数据
//{
// "today": 5,
// "all": 77
//},
//审核统计数据
//{
// "total": 6,
// "sends": 5
// },
//车流量统计数据
//{
// "today": 0,
// "all": 675338
//}
//得到表头行
Widget getHeadRow() {
Widget _headRow;
switch (widget.statisType) {
case 'zptj':
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(475),
child: _getSortBtn(sortField: 'dwmc', left: 78),
),
SizedBox(
width: ScreenUtil().setWidth(285),
child: _getSortBtn(sortField: 'today', left: 10),
),
SizedBox(
width: ScreenUtil().setWidth(280),
child: _getSortBtn(sortField: 'all', left: 10),
),
],
);
break;
case 'sh_hyc_tj':
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(495),
child: _getSortBtn(sortField: 'dwmc', left: 78),
),
SizedBox(
width: ScreenUtil().setWidth(265),
child: _getSortBtn(sortField: 'total', left: 10),
),
SizedBox(
width: ScreenUtil().setWidth(300),
child: _getSortBtn(sortField: 'sends', left: 20),
),
],
);
break;
case 'clltj':
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(465),
child: _getSortBtn(sortField: 'dwmc', left: 78),
),
// SizedBox(
// width: ScreenUtil().setWidth(265),
// child: _getSortBtn(sortField: 'today', left: 20),
// ),
// SizedBox(
// width: ScreenUtil().setWidth(300),
// child: _getSortBtn(sortField: 'all', left: 50),
// ),
SizedBox(
width: ScreenUtil().setWidth(265),
child: Text(''),
),
SizedBox(
width: ScreenUtil().setWidth(300),
child: _getSortBtn(sortField: 'today', left: 20),
),
],
);
break;
default:
return Container();
break;
}
return _headRow;
}
/*
listAllStatisData =
[
{
"id": 1,
"dwip": "172.16.3.1",
"dwmc": "锦绣花园",
"zp_all": 54,
"hyc_all": 53,
"zp_today": 1,
"sends": 1,
"send_all": 34,
"csnum": 1,
"fsnum": 1,
"cll_today": 23200,
"cll_all": 3242513
},
...
]
*/
//得到统计行
Widget getStatisRow() {
Widget _headRow;
switch (widget.statisType) {
case 'zptj':
List _listSum = tj_getAllSum('zp_today');
List _listAll = tj_getAllSum('zp_all');
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(455),
//xx个点位正常\n(共xx个点位)
child: _getStatisText(
//text: '${getOKdw().toString()}个点位正常\n(共${listDwinfoGetList2.length.toString()}个点位)',
text: '共 ${listDwinfoGetList2.length.toString()} 个点位',
left: ScreenUtil().setWidth(170)),
),
SizedBox(
width: ScreenUtil().setWidth(270),
//xx个点位,今日共抓拍xx
child: _getStatisText(
//text: '${_listSum[0].toString()}个点位,今日共抓拍${_listSum[1].toString()}',
text: '今日 ${_listSum[1].toString()} 次',
width: ScreenUtil().setWidth(245)),
),
SizedBox(
width: ScreenUtil().setWidth(300),
//xx个点位,总共抓拍xx
child: _getStatisText(
//text: '${_listAll[0].toString()}个点位,总共抓拍${_listAll[1].toString()}',
text: '总共 ${_listAll[1].toString()} 次',
width: ScreenUtil().setWidth(260)),
),
],
);
break;
case 'sh_hyc_tj':
List _listSum = tj_getAllSum('send_all');
//List _listAll = tj_getAllSumCll('total'); // 'total' 字段没有记录详情,所以用tj_getAllSumCll()
List _listAll = tj_getAllSum('hyc_all');
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(475),
//xx正常(共13)
child: _getStatisText(
//text: '${getOKdw().toString()}个点位正常\n(共${listDwinfoGetList2.length.toString()}个点位)',
text: '共 ${listDwinfoGetList2.length.toString()} 个点位',
left: ScreenUtil().setWidth(170)),
),
SizedBox(
width: ScreenUtil().setWidth(260),
//xx个点位,总共审核xx
child: _getStatisText(
//text: '${_listAll[0].toString()}个点位,总共审核${_listAll[1].toString()}',
text: '共审核 ${_listAll[1].toString()} 次',
width: ScreenUtil().setWidth(225)),
),
SizedBox(
//xx个点位,总共推送xx
child: _getStatisText(
//text: '${_listSum[0].toString()}个点位,总共推送${_listSum[1].toString()}',
text: '共推送 ${_listSum[1].toString()} 次',
width: ScreenUtil().setWidth(260)),
),
],
);
break;
case 'clltj':
List _listSum = tj_getAllSum('cll_today');
List _listAll = tj_getAllSum('cll_all');
_headRow = Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(
width: ScreenUtil().setWidth(445),
//xx个点位正常\n(共xx个点位)
child: _getStatisText(
//text: '${getOKdw().toString()}个点位正常\n(共${listDwinfoGetList2.length.toString()}个点位)',
text: '共 ${listDwinfoGetList2.length.toString()} 个点位',
left: ScreenUtil().setWidth(150)),
),
// SizedBox(
// width: ScreenUtil().setWidth(280),
// //xx个点位,今日共抓拍xx
// child: _getStatisText(
// //text: '${_listSum[0].toString()}个点位,今日车流量${_listSum[1].toString()}',
// text: '今日 ${_listSum[1].toString()}',
// width: ScreenUtil().setWidth(265)),
// ),
// SizedBox(
// width: ScreenUtil().setWidth(280),
// //xx个点位,总共抓拍xx
// child: _getStatisText(
// //text: '${_listAll[0].toString()}个点位,总共车流量${_listAll[1].toString()}',
// text: '总共 ${(_listAll[1] ~/ 10000).toString()} 万',
// width: ScreenUtil().setWidth(280)),
// ),
SizedBox(
width: ScreenUtil().setWidth(280),
//xx个点位,今日共抓拍xx
child: _getStatisText(
//text: '${_listSum[0].toString()}个点位,今日车流量${_listSum[1].toString()}',
text: '',
width: ScreenUtil().setWidth(265)),
),
SizedBox(
width: ScreenUtil().setWidth(280),
//xx个点位,今日共抓拍xx
child: _getStatisText(
//text: '${_listSum[0].toString()}个点位,今日车流量${_listSum[1].toString()}',
text: '今日 ${_listSum[1].toString()}',
width: ScreenUtil().setWidth(205)),
),
],
);
break;
default:
return Container();
break;
}
return _headRow;
}
//获取已审核黑烟车统计数据:App.Car_Statis.GetStaHyc
//{
// "ret": 200,
// "data": {
// "total": 40,
// "sends": {
// "total": 0,
// "data": []
// },
// "csnum": {
// "total": 0,
// "data": []
// },
// "fsnum": {
// "total": 0,
// "data": []
// }
// },
// "msg": ""
// }
//获取抓拍统计数据:App.Car_Statis.GetStaYjxx
//{
// "ret": 200,
// "data": {
// "today": {
// "total": 0,
// "data": []
// },
// "all": 40
// },
// "msg": ""
// }
//得到 listAllStatisData[field] 的统计数据,
//适用的字段:抓拍统计的'today'、all;审核统计的"total"、"sends";
List<int> tj_getAllSum(String field) {
int items = 0;
int sum = 0;
for (var item in listAllStatisData) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
//获取车流量统计数据:App.Car_Statis.GetStaCll
//{
// "ret": 200,
// "data": {
// "today": 7010,
// "all": 1640350
// },
// "msg": ""
//}
//得到 listZptjStatis[field] 的统计数据,
//适用的字段:车流量统计的'today'、all
List<int> tj_getAllSumCll(String field) {
int items = 0;
int sum = 0;
for (var item in listZptjStatis) {
if (item[field] > 0) {
items++;
sum += item[field];
}
}
return [items, sum];
}
Widget _getStatisText({@required String text, double left = 0, double width = 100}) {
return Row(
children: [
SizedBox(width: ScreenUtil().setWidth(left)),
Container(
width: width,
child:
Text(text, style: TextStyle(fontSize: 12), maxLines: 2, textAlign: TextAlign.center),
),
//SizedBox(width: ScreenUtil().setWidth(20)),
],
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: Size.fromHeight(ScreenUtil().setHeight(173)), // 设置appBar高度
// 设置appBar高度
child: AppBar(
automaticallyImplyLeading: false,
centerTitle: true,
titleSpacing: 0.0,
flexibleSpace: Container(
//SizedBox(height: ScreenUtil().statusBarHeight), //显示顶部状态栏
// SizedBox(height: ScreenUtil().setHeight(10)), //显示顶部状态栏
padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight), //留出顶部状态栏高度
child: Container(
//height: ScreenUtil().setHeight(173),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
// decoration: BoxDecoration(
// gradient: LinearGradient(colors: [
// Color(0xFF0018EB),
// Color(0xFF01C1D9),
// ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
// ),
),
),
title: Padding(
padding: EdgeInsets.only(left: 0, right: 0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
getIconAndTextButton(
iconColor: Colors.white,
iconData: Icons.chevron_left_outlined,
onPress: () {
Navigator.pop(context);
},
),
Expanded(
child: Text(mapStatisType[widget.statisType]['text'],
style: TextStyle(color: Colors.white, fontSize: 20),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis),
),
SizedBox(width: 10),
],
),
),
actions: [
InkWell(
child: Image.asset(
widget.statisType == 'zptj'
? 'assets/images/statis_blue.png'
: widget.statisType == 'sh_hyc_tj'
? 'assets/images/statis_red.png'
: 'assets/images/statis_green.png',
width: 32,
height: 32,
color: Colors.white),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) {
if (widget.statisType == 'clltj') {
return ZptjBarChartOne(
data_ok: true, //listAllStatisData 中的数据已经准备好
statisType: widget.statisType,
);
} else {
return ZptjBarChart(
data_ok: true, //listAllStatisData 中的数据已经准备好
statisType: widget.statisType,
);
}
}),
);
},
),
SizedBox(width: 15),
],
),
),
body: (listAllStatisData.isEmpty)
? getMoreWidget(color: Colors.black38)
: Column(
children: [
SizedBox(height: ScreenUtil().setHeight(20)),
getHeadRow(), //得到表头行
SizedBox(height: ScreenUtil().setHeight(20)),
Divider(height: 1.0, color: Colors.blue),
SizedBox(height: ScreenUtil().setHeight(10)),
getStatisRow(), //得到统计行
SizedBox(height: ScreenUtil().setHeight(10)),
Divider(height: 1.0, color: Colors.blue),
Expanded(
child: ListView.builder(
itemCount: listAllStatisData.length,
itemBuilder: (BuildContext context, index) {
return Column(
children: <Widget>[
_getListTile(context, index),
Divider(height: 1.0),
],
);
},
),
),
],
),
);
}
Widget _getImage(String sortField) {
sortField = (sortField == 'dwmc' ? 'id' : sortField);
String _image = _sortField != sortField
? 'assets/images/sort.png'
: _descending
? 'assets/images/descending.png'
: 'assets/images/ascending.png';
return Container(
margin: EdgeInsets.only(top: 4),
height: ScreenUtil().setWidth(38),
width: ScreenUtil().setWidth(38),
//child: Image.asset('assets/images/ybsthbj.png', fit: BoxFit.fitHeight),
child: Image.asset(_image,
fit: BoxFit.cover,
color: isLoading
? Theme.of(context).disabledColor
: (_sortField == sortField ? Colors.blue : null)));
}
String _sortField = 'dwmc';
bool _descending = false; //默认升序排列
Widget _getSortBtn({@required String sortField, double left = 0}) {
return InkWell(
// color: Colors.white,
// padding: EdgeInsets.all(0),
//iconSize: this.iconSize,
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
children: [
SizedBox(width: ScreenUtil().setWidth(left)),
Text(mapTjDataText[sortField],
style: TextStyle(
fontSize: 18,
color: Colors.blue,
fontWeight: _sortField == sortField || (_sortField == 'id' && sortField == 'dwmc')
? FontWeight.bold
: null)),
SizedBox(width: ScreenUtil().setWidth(20)),
_getImage(sortField),
],
),
onTap: () {
if (isLoading) {
return;
}
print('sortField = $sortField,_descending = $_descending');
//按照用户选择的 sortField、_descending对listSbbjGetList2进行排序,并延时更新
_listSort(sortField: sortField == 'dwmc' ? 'id' : sortField);
},
);
}
// Map<String, String> mapTjDataText = {
// "dwip": '点位IP',
// "today": '今日',
// "all": '总共',
// "total": '总共2',
// "sends": '推送'
// };
//按照用户选择的 sortField、_descending对listZptjStatis进行排序,并延时更新
Future _listSort({@required String sortField, bool bShowToast = false}) {
if (!isLoading && listAllStatisData.length > 0) {
isLoading = true;
try_setState();
if (_sortField == sortField) {
_descending = !_descending; //若是与上一次按同一个自动排序,则切换升序降序
} else {
_descending = false; //默认升序排列
}
switch (sortField) {
default:
if (_descending) {
//按 sortField 降序排序
listAllStatisData.sort((a, b) => (b[sortField]).compareTo(a[sortField]));
} else {
//按 sortField 升序排序
listAllStatisData.sort((a, b) => (a[sortField]).compareTo(b[sortField]));
}
break;
}
Future.delayed(const Duration(milliseconds: 1000), () {
if (bShowToast) {
Fluttertoast.showToast(
msg:
'按“${mapTjDataText[sortField == 'id' ? 'dwmc' : sortField]}”${_descending ? '降序' : '升序'}排列完成!',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
);
}
_sortField = sortField;
isLoading = false;
try_setState(); //避免如下异常报错
});
}
}
}
+280
View File
@@ -0,0 +1,280 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import '../../model/ProductModel.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import '../../config/Config.dart';
import 'package:dio/dio.dart';
// import '../../services/SignServices.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
//轮播图类模型
import '../../model/FocusModel.dart';
class HomePage extends StatefulWidget {
HomePage({Key key}) : super(key: key);
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage>
with AutomaticKeepAliveClientMixin {
List _focusData = [];
List _hotProductList = [];
List _bestProductList = [];
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_getFocusData();
_getHotProductData();
_getBestProductData();
// SignServices.getSign();
}
//获取轮播图数据
_getFocusData() async {
var api = '${Config.domain}api/focus';
var result = await Dio().get(api);
var focusList = FocusModel.fromJson(result.data);
setState(() {
this._focusData = focusList.result;
});
}
//获取猜你喜欢的数据
_getHotProductData() async {
var api = '${Config.domain}api/plist?is_hot=1';
var result = await Dio().get(api);
var hotProductList = ProductModel.fromJson(result.data);
setState(() {
this._hotProductList = hotProductList.result;
});
}
//获取热门推荐的数据
_getBestProductData() async {
var api = '${Config.domain}api/plist?is_best=1';
var result = await Dio().get(api);
var bestProductList = ProductModel.fromJson(result.data);
setState(() {
this._bestProductList = bestProductList.result;
});
}
//轮播图
Widget _swiperWidget() {
if (this._focusData.length > 0) {
return Container(
child: AspectRatio(
aspectRatio: 2 / 1,
child: Swiper(
itemBuilder: (BuildContext context, int index) {
String pic = this._focusData[index].pic;
pic = Config.domain + pic.replaceAll('\\', '/');
return new Image.network(
"${pic}",
fit: BoxFit.fill,
);
},
itemCount: this._focusData.length,
pagination: new SwiperPagination(),
autoplay: true),
),
);
} else {
return Text('加载中...');
}
}
Widget _titleWidget(value) {
return Container(
height: ScreenUtil().setHeight(60),
margin: EdgeInsets.only(left: ScreenUtil().setWidth(20)),
padding: EdgeInsets.only(left: ScreenUtil().setWidth(20)),
decoration: BoxDecoration(
border: Border(
left: BorderSide(
color: Colors.red,
width: ScreenUtil().setWidth(10),
))),
child: Text(
value,
style: TextStyle(color: Colors.black54),
),
);
}
//热门商品
Widget _hotProductListWidget() {
if (this._hotProductList.length > 0) {
return Container(
height: ScreenUtil().setHeight(234),
padding: EdgeInsets.all(ScreenUtil().setWidth(20)),
child: ListView.builder(
scrollDirection: Axis.horizontal,
itemBuilder: (contxt, index) {
//处理图片
String sPic = this._hotProductList[index].sPic;
sPic = Config.domain + sPic.replaceAll('\\', '/');
return Column(
children: <Widget>[
Container(
height: ScreenUtil().setHeight(140),
width: ScreenUtil().setWidth(140),
margin: EdgeInsets.only(right: ScreenUtil().setWidth(21)),
child: Image.network(sPic, fit: BoxFit.cover),
),
Container(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
height: ScreenUtil().setHeight(50),
child: Text(
"¥${this._hotProductList[index].price}",
style: TextStyle(color: Colors.red),
),
)
],
);
},
itemCount: this._hotProductList.length,
),
);
} else {
return Text("");
}
}
//推荐商品
Widget _recProductListWidget() {
var itemWidth = (ScreenUtil().screenWidth - 30) / 2;
return Container(
padding: EdgeInsets.all(10),
child: Wrap(
runSpacing: 10,
spacing: 10,
children: this._bestProductList.map((value) {
//图片
String sPic = value.sPic;
sPic = Config.domain + sPic.replaceAll('\\', '/');
return InkWell(
onTap: () {
Navigator.pushNamed(context, '/productContent',
arguments: {"id": value.sId});
},
child: Container(
padding: EdgeInsets.all(10),
width: itemWidth,
decoration: BoxDecoration(
border: Border.all(
color: Color.fromRGBO(233, 233, 233, 0.9), width: 1)),
child: Column(
children: <Widget>[
Container(
width: double.infinity,
child: AspectRatio(
//防止服务器返回的图片大小不一致导致高度不一致问题
aspectRatio: 1 / 1,
child: Image.network(
"${sPic}",
fit: BoxFit.cover,
),
),
),
Padding(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(20)),
child: Text(
"${value.num}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(color: Colors.black54),
),
),
Padding(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(20)),
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.centerLeft,
child: Text(
"¥${value.price}",
style: TextStyle(color: Colors.red, fontSize: 16),
),
),
Align(
alignment: Alignment.centerRight,
child: Text("¥${value.oldPrice}",
style: TextStyle(
color: Colors.black54,
fontSize: 14,
decoration: TextDecoration.lineThrough)),
)
],
),
)
],
),
),
);
}).toList(),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.center_focus_weak, size: 28, color: Colors.black87),
onPressed: null,
),
title: InkWell(
child: Container(
height: ScreenUtil().setHeight(68),
decoration: BoxDecoration(
color: Color.fromRGBO(233, 233, 233, 0.8),
borderRadius: BorderRadius.circular(30)),
padding: EdgeInsets.only(left: 10),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Icon(Icons.search),
Text("笔记本", style: TextStyle(fontSize: ScreenUtil().setSp(28)))
],
),
),
onTap: () {
Navigator.pushNamed(context, '/search');
},
),
actions: <Widget>[
IconButton(
icon: Icon(Icons.message, size: 28, color: Colors.black87),
onPressed: null,
)
],
),
body: ListView(
children: <Widget>[
_swiperWidget(),
SizedBox(height: ScreenUtil().setHeight(20)),
_titleWidget("猜你喜欢"),
SizedBox(height: ScreenUtil().setHeight(20)),
_hotProductListWidget(),
_titleWidget("热门推荐"),
_recProductListWidget()
],
),
);
}
}
+186
View File
@@ -0,0 +1,186 @@
import 'package:badges/badges.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:hyzp_ybqx/pages/tabs/page4_myMsics_new.dart';
//import '../../widget/player_pro.dart';
import '../../components/commonFun.dart';
//import 'package:fijkplayer/fijkplayer.dart';
import '../../services/ServiceLocator.dart';
import '../../services/Storage.dart';
import 'page1_work.dart';
class Tabs extends StatefulWidget {
Tabs({Key key, this.arguments = 0}) : super(key: key);
int arguments;
_TabsState createState() => _TabsState();
}
class _TabsState extends State<Tabs> {
//try_setState(); //避免如下异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
int _currentIndex = 0;
String sAppBar0 = 'Flutter Demo';
String sAppBar = 'Flutter Demo';
PageController _pageController;
@override
void initState() {
getlistItems().then((value) => try_setState());
print('widget.arguments = ${widget.arguments}');
//_currentIndex = 3 == widget.arguments ? 0 : widget.arguments; //解决"我的"页面根据用户所属组及时刷新问题
_currentIndex = widget.arguments;
this._pageController = PageController(initialPage: _currentIndex);
// 注册服务
setupLocator();
// 解决登录按钮再次变换文字的问题
Future.delayed(const Duration(milliseconds: 1000), () {
//重新初始化处理延时登录的变量
//bMayLogin = false; //这句必须注释掉,否则“退出登录”后,无法再次进行用户名登录
bPreLoading = false;
bLoginVerify = false; //处理延时登录,判断用户名登录是否验证通过
});
super.initState();
}
double _activeIconWidth = 68;
Future getlistItems() async {
listItems.addAll([
BottomNavigationBarItem(
icon: getImageItem('assets/images/矢量智能对象.png'),
label: "首页",
activeIcon: getImageItem('assets/images/矢量智能对象.png',
width: _activeIconWidth, color: Colors.blue)),
BottomNavigationBarItem(
icon: getImageItem('assets/images/矢量智能对象(1).png'),
label: "统计",
activeIcon: getImageItem('assets/images/矢量智能对象(1).png',
width: _activeIconWidth, color: Colors.blue)),
BottomNavigationBarItem(
icon: getImageItem('assets/images/矩形 1 拷贝 39.png'),
label: "设备",
activeIcon: getImageItem('assets/images/矩形 1 拷贝 39.png',
width: _activeIconWidth, color: Colors.blue)),
//bNewVer:是否发现新版本
BottomNavigationBarItem(
icon: getImageItem('assets/images/我的.png', bBadge: bNewVer),
label: "我的",
activeIcon: getImageItem('assets/images/我的.png',
width: _activeIconWidth, color: Colors.blue, bBadge: bNewVer)),
]);
}
// 添加底部导航栏图标的小红点
Widget getImageItem(String imagePath,
{double width = 56,
Color color = const Color.fromRGBO(131, 131, 131, 1),
bool bBadge = false}) {
return bBadge
? Badge(
position: BadgePosition.topEnd(top: -4, end: -9),
badgeContent: null,
child: Image.asset(imagePath,
width: ScreenUtil().setWidth(width), fit: BoxFit.cover, color: color))
: Image.asset(imagePath,
width: ScreenUtil().setWidth(width), fit: BoxFit.cover, color: color);
}
List<BottomNavigationBarItem> listItems = [];
//该美工优化的页面 Page1_Works,是供多个页面共享的代码框架。不同的页面以 PageType 字段进行区分
//String pageType = ''; //'home_page'、'statis_page'、'device_page'
List<Widget> _pageList = [
Page1_Works(pageType: 'home_page', title: '黑烟车抓拍系统'),
Page1_Works(pageType: 'statis_page', title: ' 统计信息'),
Page1_Works(pageType: 'device_page', title: ' 设备管理'),
//Page2_StatisticsNew(),
//Page3_Device(),
//Page4_MyMsics(),
Page4_MyMsicsNew(pageType: 'my_page', title: ' 我的'),
];
Text _getName(index) {
return Text(this.sAppBar0 + ' - ' + this.listItems[_currentIndex].label);
}
@override
Widget build(BuildContext context) {
sizeWindowPhysicalSize = MediaQuery.of(context).size;
return Scaffold(
// appBar: _currentIndex!=3?:AppBar(
// title: Text("用户中心"),
// ),
resizeToAvoidBottomPadding: false, //解决输入法键盘弹出越界问题-OK
appBar: PreferredSize(
child: AppBar(
//title: Text("Flutter Demo"),
title: listItems.isEmpty ? Text('') : _getName(this._currentIndex),
),
preferredSize: Size.fromHeight(0) //Flutter——设置appBar的高度
),
//底部导航栏,使用PageView方式,在App启动时只加载显示页面,启动时没有警告报错。可以配置每个页面的是否保持状态,更为灵活,也更复杂一些
body: PageView(
controller: this._pageController,
children: this._pageList,
onPageChanged: (index) {
setState(() {
this._currentIndex = index;
//label: "我的"
//eventBus.fire(GroupIdUpdateEvent('g_userInfo.userGroupIDlist 数据已更新')); //这样刷新有效
// if (3 == index) {
// }
});
},
physics: NeverScrollableScrollPhysics(), //禁止pageView滑动
),
//底部导航栏,使用IndexedStack方式,是在App启动时便一次性加载所有页面,启动时有警告报错。所有页面的状态都会保持
// body: IndexedStack(
// index: _currentIndex,
// children: this._pageList,
// ),
bottomNavigationBar: listItems.isEmpty
? Text('')
: BottomNavigationBar(
currentIndex: _currentIndex,
onTap: (index) {
//eventBus.fire(GroupIdUpdateEvent('g_userInfo.userGroupIDlist 数据已更新')); //这样刷新有效
g_iIndex = index;
Storage.setString('tabs_index', g_iIndex.toString());
setState(() {
this._currentIndex = index;
this._pageController.jumpToPage(index);
// if (1 == index && bPlaying) {
// if (player.value.videoRenderStart && player.state == FijkState.paused) {
// player.start();
// }
// } else {
// //若player并未初始化播放,调用会报错:The method 'changePlayerState' was called on null.
// if (player.value.videoRenderStart && player.state == FijkState.started) {
// bPlaying = true;
// player.pause();
// }
// }
});
},
iconSize: ScreenUtil().setSp(70),
//icon的大小
fixedColor: Colors.blueAccent,
type: BottomNavigationBarType.fixed,
items: listItems,
),
);
}
}
+144
View File
@@ -0,0 +1,144 @@
//https://material.io/tools/icons/?icon=favorite&style=baseline
import 'package:flutter/material.dart';
import '../../widget/JdButton.dart';
import '../../services/UserServices.dart';
import '../../services/EventBus.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
class UserPage extends StatefulWidget {
UserPage({Key key}) : super(key: key);
_UserPageState createState() => _UserPageState();
}
class _UserPageState extends State<UserPage> {
bool isLogin = false;
List userInfo = [];
@override
void initState() {
// TODO: implement initState
super.initState();
this._getUserinfo();
//监听登录页面改变的事件
eventBus.on<UserEvent>().listen((event) {
print(event.str);
this._getUserinfo();
});
}
_getUserinfo() async {
var isLogin = await UserServices.getUserLoginState();
var userInfo = await UserServices.getUserInfo();
setState(() {
this.userInfo = userInfo;
this.isLogin = isLogin;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text("用户中心"),
// ),
body: ListView(
children: <Widget>[
Container(
height: ScreenUtil().setHeight(220),
width: double.infinity,
decoration:
BoxDecoration(image: DecorationImage(image: AssetImage('assets/images/user_bg.jpg'), fit: BoxFit.cover)),
child: Row(
children: <Widget>[
Container(
margin: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ClipOval(
child: Image.asset(
'assets/images/user.png',
fit: BoxFit.cover,
width: ScreenUtil().setWidth(100),
height: ScreenUtil().setWidth(100),
),
),
),
!this.isLogin
? Expanded(
flex: 1,
child: InkWell(
onTap: () {
Navigator.pushNamed(context, '/login');
},
child: Text("登录/注册", style: TextStyle(color: Colors.white)),
),
)
: Expanded(
flex: 1,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("用户名:${this.userInfo[0]["username"]}",
style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(32))),
Text("普通会员", style: TextStyle(color: Colors.white, fontSize: ScreenUtil().setSp(24))),
],
),
)
],
),
),
ListTile(
leading: Icon(Icons.assignment, color: Colors.red),
title: Text("全部订单"),
onTap: () {
Navigator.pushNamed(context, '/order');
},
),
Divider(),
ListTile(
leading: Icon(Icons.payment, color: Colors.green),
title: Text("待付款"),
),
Divider(),
ListTile(
leading: Icon(Icons.local_car_wash, color: Colors.orange),
title: Text("待收货"),
),
Container(width: double.infinity, height: 10, color: Color.fromRGBO(242, 242, 242, 0.9)),
ListTile(
leading: Icon(Icons.favorite, color: Colors.lightGreen),
title: Text("我的收藏"),
),
Divider(),
ListTile(
leading: Icon(Icons.people, color: Colors.black54),
title: Text("在线客服"),
),
Divider(),
this.isLogin
? Container(
padding: EdgeInsets.all(20),
child: JdButton(
height: ScreenUtil().setSp(300),
color: Colors.red,
text: "退出登录",
onTop: () {
UserServices.loginOut();
this._getUserinfo();
},
),
)
: Text("")
],
));
}
}
+990
View File
@@ -0,0 +1,990 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
// import 'package:hyzp_ybqx/pages/Works/DWSP/dw_list_sound.dart';
// import 'package:hyzp_ybqx/pages/Works/DWSP/dw_sound.dart';
import 'package:hyzp_ybqx/pages/Works/DWSP/dwsp_getList.dart';
import 'package:hyzp_ybqx/pages/Works/HYSH/hysh_getList_fliter.dart';
import 'package:hyzp_ybqx/pages/Works/HYSH/hysh_getList_new.dart';
import 'package:hyzp_ybqx/pages/Works/SBBJ/sbbj_getList.dart';
import 'package:hyzp_ybqx/pages/Works/SBGL/dwxx_getList.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/today_list.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/zptj_bar_chart.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/zptj_bar_chart_one.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/zptj_page.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../components/hyxx_data_handle.dart';
import '../Works/DWDT/basic_map.dart';
import '../Works/LED_XSXX/led_xsxx_content.dart';
///flutter中如何获取子类Widget并调用它的方法 萤火虫离别的礼物 2019.08.07 15:46:08 https://www.jianshu.com/p/b16f70dd692c
//在flutter中开发中,会发现当子类Widget是StatefulWidget类型的时候,想要获取它的State并调用State中的方法,感觉无从下手。
// 不像是在iOS中,可以直接调用一个类的公开的方法,flutter可以通过key来实现。每个Widget都是唯一标识的。此唯一标识对应于可选的Key参数。
// 如果省略,Flutter将为您生成一个。key主要分为四种:GlobalKey,LocalKey,UniqueKey或ObjectKey,GlobalKey确保key是在整个应用程序唯一的,
// 这次我们就要使用它来实现。我们需要给子Widget定义一个唯一的GlobalKey,然后根据这个key获取到这个Widget,进行相关的操作,下面是相关的代码:
//这里就是关键的代码,定义一个key
//GlobalKey<MyFijkPanelWidgetBuilderState> _myFijkPanelWidgetBuilderStateKey = new GlobalKey<MyFijkPanelWidgetBuilderState>();
class Page1_Works extends StatefulWidget {
Page1_Works({@required this.pageType, this.title, Key key}) : super(key: key);
//该美工优化的页面 Page1_Works,是供多个页面共享的代码框架。不同的页面以 PageType 字段进行区分
String pageType = ''; //'home_page'、'statis_page'、'device_page'
String title = '';
@override
_Page1_WorksState createState() => _Page1_WorksState();
}
//class _Page1WorkState extends State<Page1Work> with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
class _Page1_WorksState extends State<Page1_Works>
with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
//Begin:底部导航栏,使用PageView方式,配置每页面的保持状态。必须添加继承:with AutomaticKeepAliveClientMixin
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
//End:底部导航栏,使用PageView方式,配置每页面的保持状态
// final FijkPlayer player = FijkPlayer();
// bool bFirstPlay;
@override
void initState() {
// getDataListFun().then((list) {
// _listBtnItems = list;
// try_setState();
// });
//startGetStatisData(); //已经在 _MyAppState 中提前开始获取统计数据
updateStatisData();
//监听统计数据改变事件
eventBus.on<StatisDataUpdate>().listen((event) {
print(event.str);
updateStatisData();
});
//监听 选择LED点位 更新事件
eventBus.on<SelectLedDwUpdateEvent>().listen((event) async {
print(event.str);
try_setState();
});
super.initState();
}
// 更新工作页面的今日统计数据
Future updateStatisData() async {
if (-1 == mapStatisInfo['今日抓拍']) {
getAllSumNew().then((_) {
try_setState();
});
} else {
try_setState();
}
// if (listZptjStatisAlone.length >= dwSum && -1 == mapStatisInfo['今日抓拍']) {
// getAllSum('today', listZptjStatisAlone).then((value) {
// //mapStatisInfo['今日抓拍'] = value[1];
// listTodayZpjl = value[2];
// //try_setState();
// });
// }
//
// if (listTodayShtj.length >= dwSum && -1 == mapStatisInfo['今日初审']) {
// getAllSum('csnum', listTodayShtj).then((value) {
// //mapStatisInfo['今日初审'] = value[1];
// listTodayChjl = value[2];
// //try_setState();
// });
// getAllSum('fsnum', listTodayShtj).then((value) {
// //mapStatisInfo['今日复审'] = value[1];
// listTodayFhjl = value[2];
// //try_setState();
// });
// getAllSum('sends', listTodayShtj).then((value) {
// //mapStatisInfo['今日推送'] = value[1];
// listTodayTsjl = value[2];
// //try_setState();
// });
// }
//车流量统计数据用 getAllSumCll() 单独处理
// if (listClltjStatisAlone.length >= dwSum && -1 == mapStatisInfo['今日车流']) {
// getAllSumCll('today', listClltjStatisAlone).then((value) {
// mapStatisInfo['今日车流'] = value[1] ~/ 10000;
// try_setState();
// });
// }
}
Future<void> sysPop() async {
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
_Page1_WorksState();
@override
void dispose() {
super.dispose();
}
// double getHeight() {
// double _height = 0;
// for (double h in listHeight) {
// _height += h;
// }
// print("_height1 = $_height"); // 767
// _height += ScreenUtil().statusBarHeight * ScreenUtil().pixelRatio; // 系统顶部状态栏高度
// _height += ScreenUtil().bottomBarHeight * ScreenUtil().pixelRatio; // 系统底部工具栏高度
// //R:\FlutterProject\FlutterProject33\hyzp_ybqx\lib\pages\tabs\Tabs.dart中,iconSize: ScreenUtil().setSp(70),
// _height += (kBottomNavigationBarHeight * 3 + 8); // 底部导航栏的高度,this.elevation = 8.0,高度 默认8.0
// //_height += (68 * 3); // 底部导航栏的高度
// print("_height2 = $_height"); // 1015
//
// _height = ScreenUtil().screenHeight * ScreenUtil().pixelRatio - _height;
// // print("ScreenUtil().screenHeight = ${ScreenUtil().screenHeight}"); //640.0
// // print("ScreenUtil().pixelRatio = ${ScreenUtil().pixelRatio}"); // 3.0
// print("_height3 = $_height"); // S7:905 / 3 = 301 OK;
// // S7 OK:
// // I/flutter (22790): _height1 = 767.0
// // I/flutter (22790): _height2 = 1015.0
// // I/flutter (22790): _height3 = 905.0
//
// // S10 OK:
// // I/flutter (23478): _height1 = 767.0
// // I/flutter (23478): _height2 = 1055.0
// // I/flutter (23478): _height3 = 1081.0
//
// // ARS AL00 OK:
// // I/flutter ( 9979): _height1 = 767.0
// // I/flutter ( 9979): _height2 = 1039.0
// // I/flutter ( 9979): _height3 = 1101.0
//
// // AS ADV OK:
// // I/flutter ( 5464): _height1 = 767.0
// // I/flutter ( 5464): _height2 = 1006.0
// // I/flutter ( 5464): _height3 = 788.0
//
// return _height;
// }
List<double> listHeight = <double>[
484,
46,
168,
69,
];
@override
Widget build(BuildContext context) {
// double btnHeight1 = 80; //第一按钮行高度
// double btnHeight2 = 160; //第二按钮行高度
// double btnHeight3 = 302; //350、303 S7越界。第二按钮行高度,370越界,365 ARS AL00不越界
// int btnCount = 4; //每行按钮个数
// var mediaSize = MediaQuery.of(context).size;
// double ratio2 = (mediaSize.width / btnCount) / (btnHeight2 / 2);
//注意:必须在返回Widget的覆盖构造函数中初始化,在其他地方初始化会报错失败
//在使用之前请设置好设计稿的宽度和高度,传入设计稿的宽度和高度(单位px)
//一定在MaterialApp的home中的页面设置(即入口文件,只需设置一次),以保证在每次使用之前设置好了适配尺寸:
//默认 width : 1080px , height:1920px , allowFontScaling:false
//ScreenUtil.init(context);
// double myWidth = mediaSize.width;
// double myHeight = mediaSize.width * 9 / 16;
// print('My_viewSize: Width-$myWidth, Height-$myHeight');
// double ratio = 1.0;
//getHeight();
return WillPopScope(
child: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(244, 244, 244, 1), //设置背景色
),
child: Column(
children: <Widget>[
Container(
height: ScreenUtil().setHeight(listHeight[0]), //484, 530 - 46
child: Stack(
children: [
//1、第1行文字
Positioned(
child: Container(
height: ScreenUtil().setHeight(324), //181
alignment: Alignment.topCenter,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
//crossAxisAlignment: CrossAxisAlignment.start, //用的比较少
children: <Widget>[
FlatButton(
child: Container(
child: Row(
children: [
Padding(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
child: Image.asset(
'assets/images/形状 2.png',
height: ScreenUtil().setHeight(45),
),
),
Text(" 客服热线",
style: TextStyle(fontSize: 16, color: Colors.white)),
],
),
),
onPressed: () => launch("tel://18784678300"),
),
SizedBox(
width: ScreenUtil().setWidth(45),
),
Expanded(
child: Text(widget.title,
style: TextStyle(fontSize: 20.0, color: Colors.white)),
),
Container(
child: InkWell(
child: Image.asset(
'assets/images/刷新.png',
height: ScreenUtil().setHeight(45),
color: Colors.white,
),
onTap: () {
//刷新统计数据
mapStatisInfo.forEach((key, value) {
mapStatisInfo[key] = -1;
});
listDwinfoGetList2.clear();
startGetStatisDataNew();
Fluttertoast.showToast(
msg: '正在刷新统计数据...',
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
try_setState();
},
),
),
SizedBox(
width: ScreenUtil().setWidth(60),
),
],
),
),
),
//2、第2行装饰
Align(
alignment: Alignment.bottomLeft,
child: Container(
alignment: Alignment(0, 1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
//crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
height: ScreenUtil().setHeight(310),
decoration: BoxDecoration(
color: Color.fromRGBO(62, 88, 231, 1),
borderRadius: BorderRadius.horizontal(right: Radius.circular(20)),
),
//color: Colors.pinkAccent,
width: ScreenUtil().setWidth(34),
alignment: Alignment.centerRight,
),
getImageWidget(),
Container(
height: ScreenUtil().setHeight(310),
decoration: BoxDecoration(
color: Color.fromRGBO(113, 39, 203, 1),
borderRadius: BorderRadius.horizontal(left: Radius.circular(20)),
),
//color: Colors.pinkAccent,
width: ScreenUtil().setWidth(34),
alignment: Alignment.centerRight,
),
],
),
),
),
],
),
),
//3、第3行统计信息
SizedBox(height: ScreenUtil().setHeight(listHeight[1])), // 46
Container(
padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
alignment: Alignment.center,
width: ScreenUtil().setWidth(1022),
height: ScreenUtil().setHeight(listHeight[2]),
//168
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.all(Radius.circular(10)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
getStatisInfo(
'今日抓拍', listAllStatisData.length < dwSum ? -1 : mapStatisInfo['今日抓拍']),
getVerticalDivider(),
getStatisInfo(
'今日初审', listAllStatisData.length < dwSum ? -1 : mapStatisInfo['今日初审']),
getVerticalDivider(),
getStatisInfo(
'今日复审', listAllStatisData.length < dwSum ? -1 : mapStatisInfo['今日复审']),
getVerticalDivider(),
getStatisInfo(
'今日推送', listAllStatisData.length < dwSum ? -1 : mapStatisInfo['今日推送']),
getVerticalDivider(),
getStatisInfo(
'今日车流', listAllStatisData.length < dwSum ? -1 : mapStatisInfo['今日车流']),
// getStatisInfo(
// '今日抓拍', listZptjStatisAlone.length < dwSum ? -1 : mapStatisInfo['今日抓拍']),
// getVerticalDivider(),
// getStatisInfo('今日初审', listTodayShtj.length < dwSum ? -1 : mapStatisInfo['今日初审']),
// getVerticalDivider(),
// getStatisInfo('今日复审', listTodayShtj.length < dwSum ? -1 : mapStatisInfo['今日复审']),
// getVerticalDivider(),
// getStatisInfo('今日推送', listTodayShtj.length < dwSum ? -1 : mapStatisInfo['今日推送']),
// getVerticalDivider(),
// getStatisInfo(
// '今日车流', listClltjStatisAlone.length < dwSum ? -1 : mapStatisInfo['今日车流']),
],
),
),
SizedBox(height: ScreenUtil().setHeight(listHeight[3])), // 69
//4、第4行圆角按钮
Expanded(
//color: Colors.black,
//height: ScreenUtil().setHeight(getHeight()),
// S7:905
//height: ScreenUtil().setHeight(908),
//btnHeight3, // 302
//padding: EdgeInsets.all(10),
//padding: EdgeInsets.fromLTRB(ScreenUtil().setWidth(76), 0, ScreenUtil().setWidth(76), 0),
//padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
//color: Color.fromRGBO(224, 224, 224, 1),
//alignment: const Alignment(0, -1),
// GridView 控制太麻烦,动态生成必须用 GridView ,静态组件可以不用 GridView
// child: GridView.custom(
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: btnCount,
// mainAxisSpacing: ScreenUtil().setWidth(0),
// crossAxisSpacing: ScreenUtil().setHeight(0),
// childAspectRatio: 1,
// ),
// childrenDelegate: SliverChildBuilderDelegate((context, position) {
// //圆角按钮 155 * 155 px
// return getItemContainer(listData4[position]);
// //listData4[position];
// }, childCount: listData4.length),
// ),
child: getBtnGroup(),
),
],
),
),
onWillPop: () {
// if (player.state == FijkState.started) {
// player.pause();
// }
//解决在Page1_Work.dart页面,按系统返回键总是报错flutter keeps stopping的问题
//player.stop();
sysPop();
},
);
}
double _left = 30;
double _intervalHor = 75;
double _intervalVer = 58;
//Size _itemSize = Size(211, 230);
Size _itemSize = Size(211, 230);
List<Widget> _listBtnItems = [];
Widget getBtnGroup() {
return GridView.count(
mainAxisSpacing: ScreenUtil().setWidth(_intervalVer), //垂直间距
//crossAxisSpacing: ScreenUtil().setHeight(_intervalHor), //水平间距
//childAspectRatio: _itemSize.width / _itemSize.height,
padding:
EdgeInsets.only(left: ScreenUtil().setWidth(_left), right: ScreenUtil().setWidth(_left)),
crossAxisCount: 4, //一行的 Widget 数量
children: getDataListFun(),
);
}
Future getBtnGroup0() async {
List<Widget> listData4 = getDataListFun();
return Column(
children: [
Row(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(width: ScreenUtil().setWidth(_left)),
listData4[0],
//SizedBox(width: ScreenUtil().setWidth(101)),
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[1],
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[2],
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[3],
],
),
SizedBox(height: ScreenUtil().setHeight(78)),
Row(
//mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
SizedBox(width: ScreenUtil().setWidth(_left)),
listData4[4],
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[5],
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[6],
SizedBox(width: ScreenUtil().setWidth(_intervalHor)),
listData4[7],
],
),
],
);
}
Widget getVerticalDivider() {
return SizedBox(
width: 1,
height: ScreenUtil().setHeight(125),
child: DecoratedBox(
decoration: BoxDecoration(color: Colors.black26),
),
);
}
Widget getStatisInfo(String name, double data) {
return InkWell(
child: Container(
alignment: Alignment(0, 0),
//padding: EdgeInsets.only(top: ScreenUtil().setHeight(15)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(height: ScreenUtil().setHeight(10)),
Text(name,
style: TextStyle(fontSize: 12, color: Colors.black), textAlign: TextAlign.center),
SizedBox(height: ScreenUtil().setHeight(4)),
Row(
children: [
Text(
data < 0 ? '...' : '${data.toStringAsFixed('今日车流' == name ? 2 : 0)}',
style: TextStyle(
fontSize: 20,
color: Color.fromRGBO(48, 135, 255, 1),
fontWeight: FontWeight.bold),
),
'今日车流' == name
? Container(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(8)),
child: Text(' 万', style: TextStyle(fontSize: 10, color: Colors.black)),
)
: SizedBox.shrink(),
],
),
],
),
),
onTap: data < 0
? null
: () {
switch (name) {
case '今日抓拍':
// Navigator.of(context)
// .push(MaterialPageRoute(builder: (context) => ZptjBarChart(statisType: 'zptj')));
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'jrzp')));
break;
case '今日初审':
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'hycs')));
break;
case '今日复审':
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'hyfh')));
break;
case '今日推送':
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'tsjj')));
break;
case "今日车流":
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => ZptjBarChartOne(statisType: 'clltj')));
break;
default:
break;
}
},
onLongPress: data < 0
? null
: () {
switch (name) {
case '今日抓拍':
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'zptj')));
break;
case '今日初审':
case '今日复审':
case '今日推送':
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'sh_hyc_tj')));
break;
case "今日车流":
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'clltj')));
break;
default:
break;
}
},
);
}
//自定义带说明图标按钮函数。点击说明文字有反应
Widget _getIconAndTextButton(
{String text, IconData icon, Color iconColor = Colors.blueAccent, var onPress = null}) {
return Container(
width: 60,
height: 60,
alignment: const Alignment(0, 1),
child: FlatButton(
padding: EdgeInsets.all(0),
onPressed: onPress,
color: Colors.transparent,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
SizedBox(height: 2),
Container(
alignment: Alignment(0, -1),
height: 36,
width: 36,
decoration: BoxDecoration(
color: Colors.white,
),
child: Icon(
icon,
size: 32,
color: iconColor,
),
),
//SizedBox(height: 2),
Text(text,
//textAlign: TextAlign.center,
style: TextStyle(
fontSize: 12.0,
)),
],
),
),
);
}
//自定义带说明图片按钮函数。点击说明文字有反应
//Flutter按钮添加背景图片及文字的一种方法,记录下,上代码
//原文链接:https://blog.csdn.net/WC270607563/article/details/103148574
Widget _getPicAndTextButton(String text, String imgpath, var onPress,
{Size imageSize, IconData icon, Color iconColor = Colors.white}) {
if (null == imageSize) {
imageSize = Size(ScreenUtil().setWidth(75), ScreenUtil().setHeight(75));
}
Color _bkgColor;
switch (text) {
case "黑烟复审":
case "视频播放":
case "审核图表":
case "审核统计":
case "今日抓拍":
case "点位喊话":
_bkgColor = Color.fromRGBO(36, 206, 192, 1); //绿色
break;
case "抓拍图表":
case "抓拍统计":
case "推送交警":
case "报警信息":
case "今日推送":
case "LED字幕":
_bkgColor = Color.fromRGBO(79, 118, 230, 1); //深蓝
break;
case "点位视频":
case "车流量图表":
case "今日初审":
_bkgColor = Color.fromRGBO(116, 139, 161, 1); //深灰
break;
default:
_bkgColor = Color.fromRGBO(80, 159, 245, 1); //亮蓝
break;
}
//155 + 35 + 12 + 6 = 208
return InkWell(
child: Container(
width: ScreenUtil().setWidth(_itemSize.width),
height: ScreenUtil().setHeight(_itemSize.height),
alignment: Alignment.center,
//color: Colors.red,
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Container(
width: ScreenUtil().setWidth(155),
//S10 2280*1080,在S10正方形变长,是正常的。因为在 ScreenUtilInit 是按 1080, 1920
//ScreenUtilInit(designSize: Size(1080, 1920), //安卓手机宽高尺寸
//通过 sizeWindowPhysicalSize = window.physicalSize; 自动适应安卓手机系统分辨率,解决 S10 手机正方形变形问题
height: ScreenUtil().setHeight(155),
//color: Colors.blue,
decoration: BoxDecoration(
color: '车流量日统计' == text && cllRStatisDataGeting ? Colors.grey : _bkgColor,
borderRadius: BorderRadius.all(Radius.circular(15)),
),
alignment: Alignment.center,
child: imgpath.isNotEmpty
? Image.asset(imgpath,
fit: BoxFit.scaleDown,
color: Colors.white,
width: imageSize.width,
height: imageSize.height)
: Icon(
icon,
size: imageSize.width,
color: iconColor,
),
),
SizedBox(height: ScreenUtil().setWidth(0)),
Text(text, style: TextStyle(fontSize: 14)),
],
),
),
//cllRStatisDataGeting = true; //正在获取车流量日统计数据,禁止重入
onTap: '车流量日统计' == text && cllRStatisDataGeting ? null : onPress,
);
}
Widget _getPicAndTextButtonTest(String text, String imgpath, var onPress, {Size imageSize}) {
if (null == imageSize) {
imageSize = Size(ScreenUtil().setWidth(75), ScreenUtil().setHeight(75));
}
//155 + 35 + 12 = 202
return InkWell(
child: Container(
width: ScreenUtil().setWidth(155),
height: ScreenUtil().setHeight(155),
alignment: Alignment.center,
color: Colors.red,
),
onTap: onPress,
);
}
//该美工优化的页面 Page1_Works,是供多个页面共享的代码框架。不同的页面以 PageType 字段进行区分
//String pageType = ''; //'home_page'、'statis_page'、'device_page'
//生成功能区按钮List
List<Widget> getDataListFun() {
switch (widget.pageType) {
case 'home_page':
return getDataListFun_home_page();
break;
case 'statis_page':
return getDataListFun_statis_page();
break;
case 'device_page':
return getDataListFun_device_page();
break;
}
}
//生成功能区按钮List
List<Widget> getDataListFun_device_page() {
List<Widget> list = [];
list.add(
_getPicAndTextButton("点位信息", "assets/images/1 (194).png", () {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => DwxxGetList()));
}),
);
list.add(
_getPicAndTextButton("报警信息", "assets/images/1 (219).png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => SbbjGetList(hyshlx: 'sbbj')));
}),
);
list.add(
_getPicAndTextButton("点位视频", "assets/images/monitor2.png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => DwspGetList(hyshlx: 'dwsp')));
}),
);
return list;
}
//生成功能区按钮List
List<Widget> getDataListFun_statis_page() {
List<Widget> list = [];
list.add(
_getPicAndTextButton("抓拍图表", "assets/images/statis_blue.png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjBarChart(statisType: 'zptj')));
}),
);
list.add(
_getPicAndTextButton("审核图表", "assets/images/statis_red.png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjBarChart(statisType: 'sh_hyc_tj')));
}),
);
list.add(
_getPicAndTextButton("车流量图表", "assets/images/statis_green.png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjBarChartOne(statisType: 'clltj')));
}),
);
list.add(
_getPicAndTextButton("抓拍统计", "assets/images/图层 11.png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'zptj')));
}),
);
list.add(
_getPicAndTextButton("审核统计", "assets/images/1 (15).png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'sh_hyc_tj')));
}),
);
list.add(
_getPicAndTextButton("车流量统计", "assets/images/1 (84).png", () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => ZptjPage(statisType: 'clltj')));
}),
);
list.add(
_getPicAndTextButton(
"今日抓拍",
'',
listZptjStatisAlone.length < dwSum
? null
: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'jrzp')));
},
icon: Icons.camera_alt_outlined),
);
list.add(
_getPicAndTextButton(
"今日初审",
'',
listTodayShtj.length < dwSum
? null
: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'hycs')));
},
icon: Icons.preview_outlined),
);
list.add(
_getPicAndTextButton(
"今日复审",
'',
listTodayShtj.length < dwSum
? null
: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'hyfh')));
},
icon: Icons.rate_review_outlined),
);
list.add(
_getPicAndTextButton(
"今日推送",
'',
listTodayShtj.length < dwSum
? null
: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => TodayList(todayListLx: 'tsjj')));
},
icon: Icons.format_list_numbered_outlined),
);
// list.add(
// _getPicAndTextButton("车流量日统计", "assets/images/车流量日统计.png", () {
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => ZptjBarEchartsTrinityNew(statisType: 'cllrtj')));
// }),
// );
return list;
}
//生成功能区按钮List
List<Widget> getDataListFun_home_page() {
List<Widget> list = [];
list.add(
_getPicAndTextButton("黑烟初审", "assets/images/聚焦.png", () {
print('Icons.videocam');
//hyshlx为黑烟审核类型,用于在同一套代码中,处理'hycs'黑烟初审、'hyfh'黑烟复审
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => HyshGetListNew(hyshlx: 'hycs', title: '黑烟初审')));
}),
);
list.add(
_getPicAndTextButton("黑烟复审", "assets/images/盾 密码 安全.png", () {
print('Icons.videocam');
//hyshlx为黑烟审核类型,用于在同一套代码中,处理'hycs'黑烟初审、'hyfh'黑烟复审
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => HyshGetListNew(hyshlx: 'hyfh', title: '黑烟复审')));
}),
);
list.add(
_getPicAndTextButton("推送交警", "assets/images/警察.png", () {
print('Icons.videocam');
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => TsjjGetList(
// tsjjlx: 'tsjj',
// )));
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => HyshGetListFliter(hyshlx: 'tsjj', title: '推送交警')));
}),
);
// list.add(
// _getPicAndTextButton("复审查询", "assets/fun_icons/fun_icon_4.png", () {
// print('Icons.videocam');
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => TsjjGetList(tsjjlx: 'fhcx',)));
// }),
// );
list.add(
_getPicAndTextButton("非黑烟查询", "assets/images/1 (104).png", () {
print('Icons.videocam');
//Navigator.of(context).push(MaterialPageRoute(builder: (context) => FhycxGetList()));
Navigator.of(context).push(MaterialPageRoute(
//builder: (context) => WzxxGetList(hyshlx: 'fhycx')));
builder: (context) => HyshGetListFliter(hyshlx: 'fhycx', title: '非黑烟查询')));
}),
);
// list.add(
// _getPicAndTextButton("违章信息", "assets/fun_icons/fun_icon_5.png", () {
// //Navigator.of(context).push(MaterialPageRoute(builder: (context) => WzxxGetList()));
// Navigator.of(context)
// .push(MaterialPageRoute(builder: (context) => WzxxGetList(hyshlx: 'wzxx')));
// }),
// );
list.add(
_getPicAndTextButton("LED字幕", "assets/images/LED.png", () {
print('LED显示信息');
// Navigator.of(context)
// .push(MaterialPageRoute(builder: (context) => LedXsxxGetList(hyshlx: 'led_xsxx')));
//应公司要求改为:打开LED字幕后,直接显示点位选择那个界面,用户可以手动切换进行设置
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => LedXsxxContent(
title: 'LED显示信息',
sbgllx: 'led_xsxx', //设备管理类型:LED显示信息
id: 1,
)));
}),
);
list.add(
_getPicAndTextButton("点位地图", 'assets/images/1 (177).png', () {
print('点位地图');
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => BasicMap(hyshlx: 'dwdt', title: "点位地图")));
}),
);
list.add(
_getPicAndTextButton("点位视频", "assets/images/monitor2.png", () {
print('点位视频');
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => DwspGetList(hyshlx: 'dwsp')));
}),
);
// list.add(
// _getPicAndTextButton("点位喊话", "assets/images/点位喊话.png", () {
// print('点位喊话');
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => DwListSound()));
// }),
// );
// list.add(
// _getPicAndTextButton("视频播放", 'assets/images/播放 (1).png', () {
// print('视频播放');
// urlnew =
// "http://www.yibinu.edu.cn/__local/5/35/DF/264049B7E978EEE2F5849688986_05D4A6FE_152CDB8C.mp4?e=.mp4";
// Navigator.of(context).push(MaterialPageRoute(builder: (context) => PlayerProNew()));
// }),
// );
//填充空白
//list.add(null);
// list.add(
// _getPicAndTextButton("X5视频", "assets/images/monitor2.png", () {
// print('X5视频');
// Navigator.of(context)
// .push(MaterialPageRoute(builder: (context) => X5WebviewPage()));
// }),
// );
return list;
}
//生成容器部件
Widget getItemContainer0(Widget item) {
return Container(
width: 5.0,
height: 5.0,
alignment: Alignment.center,
child: item,
color: Colors.white,
);
}
//生成容器部件
Widget getItemContainer(Widget item) {
return Container(
decoration: BoxDecoration(
//color: Colors.blue,
borderRadius: BorderRadius.all(Radius.circular(20)),
),
// width: 3.0,
// height: 3.0,
alignment: Alignment.center,
child: item,
//color: Colors.blue,
);
}
}
+744
View File
@@ -0,0 +1,744 @@
import 'dart:convert';
import 'dart:io';
import 'package:badges/badges.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/commonFun.dart';
import 'package:hyzp_ybqx/pages/Login/FaceLogin.dart';
import 'package:hyzp_ybqx/pages/Login/FaceReg.dart';
import 'package:hyzp_ybqx/pages/MyMsics/05_updated/MyUpdatedNew.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/JdButton.dart';
import 'package:package_info/package_info.dart';
import 'package:package_info/package_info.dart';
import 'package:path_provider/path_provider.dart';
//import 'package:hyzp_ybqx/widget/player_pro.dart';
import 'package:scroll_to_index/util.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../components/commonFun.dart';
import '../../components/commonFun.dart';
import '../../components/customDialogF.dart';
import '../../services/Storage.dart';
//import 'package:hyzp_ybqx/widget/player_pro.dart';
import '../Login/ModifyPassword.dart';
import '../MyMsics/03_personal/PersonalData.dart';
import '../MyMsics/04_MyFeedback/MyFeedback.dart';
import '../MyMsics/05_updated/MyUpdated.dart';
import '../MyMsics/07_myAbout/MyAbout.dart';
///flutter中如何获取子类Widget并调用它的方法 萤火虫离别的礼物 2019.08.07 15:46:08 https://www.jianshu.com/p/b16f70dd692c
//在flutter中开发中,会发现当子类Widget是StatefulWidget类型的时候,想要获取它的State并调用State中的方法,感觉无从下手。
// 不像是在iOS中,可以直接调用一个类的公开的方法,flutter可以通过key来实现。每个Widget都是唯一标识的。此唯一标识对应于可选的Key参数。
// 如果省略,Flutter将为您生成一个。key主要分为四种:GlobalKey,LocalKey,UniqueKey或ObjectKey,GlobalKey确保key是在整个应用程序唯一的,
// 这次我们就要使用它来实现。我们需要给子Widget定义一个唯一的GlobalKey,然后根据这个key获取到这个Widget,进行相关的操作,下面是相关的代码:
//这里就是关键的代码,定义一个key
//GlobalKey<MyFijkPanelWidgetBuilderState> _myFijkPanelWidgetBuilderStateKey = new GlobalKey<MyFijkPanelWidgetBuilderState>();
class Page4_MyMsicsNew extends StatefulWidget {
Page4_MyMsicsNew({@required this.pageType, this.title, Key key}) : super(key: key);
//该美工优化的页面 Page4_MyMsicsNew,是供多个页面共享的代码框架。不同的页面以 PageType 字段进行区分
String pageType = ''; //'my_page'
String title = '';
@override
_Page4_MyMsicsNewState createState() => _Page4_MyMsicsNewState();
}
//class _Page1WorkState extends State<Page1Work> with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
class _Page4_MyMsicsNewState extends State<Page4_MyMsicsNew>
with WidgetsBindingObserver, AutomaticKeepAliveClientMixin {
//Begin:底部导航栏,使用PageView方式,配置每页面的保持状态。必须添加继承:with AutomaticKeepAliveClientMixin
//try_setState(); //避免异常报错
try_setState() {
try {
setState(() {});
} catch (e) {
print('setState(() {})异常:${e}');
}
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
//End:底部导航栏,使用PageView方式,配置每页面的保持状态
// final FijkPlayer player = FijkPlayer();
// bool bFirstPlay;
@override
void initState() {
//监听 g_userInfo.userGroupIDlist 更新事件
// eventBus.on<GroupIdUpdateEvent>().listen((event) async {
// print(event.str);
// getAdminItem();
// });
getListView().then((value) {
Future.delayed(Duration(milliseconds: 500), () {
getAdminItem();
});
});
super.initState();
}
Future updateStatisData() async {
if (listZptjStatisAlone.length >= dwSum && -1 == mapStatisInfo['今日抓拍']) {
getAllSum('today', listZptjStatisAlone).then((value) {
mapStatisInfo['今日抓拍'] = value[1];
try_setState();
});
}
if (listShtjStatisAlone.length >= dwSum && -1 == mapStatisInfo['今日初审']) {
getAllSum('total', listShtjStatisAlone).then((value) {
mapStatisInfo['今日初审'] = value[1];
mapStatisInfo['今日复审'] = value[1];
try_setState();
});
getAllSum('sends', listShtjStatisAlone).then((value) {
mapStatisInfo['今日推送'] = value[1];
try_setState();
});
}
if (listClltjStatisAlone.length >= dwSum && -1 == mapStatisInfo['今日车流']) {
getAllSum('today', listClltjStatisAlone).then((value) {
mapStatisInfo['今日车流'] = value[1] ~/ 10000;
try_setState();
});
}
}
Future<void> sysPop() async {
await SystemChannels.platform.invokeMethod('SystemNavigator.pop');
}
_Page4_MyMsicsNewState();
@override
void dispose() {
super.dispose();
}
//自定义方法
static onNullFun() {}
Widget _getListTile(title,
{String leadPath = '',
Color leadColor,
onTapFun = onNullFun,
onLongPressFun = onNullFun,
size = 16.0,
bool bBadge = false}) {
return Column(
children: <Widget>[
ListTile(
leading: bBadge
? Badge(
position: BadgePosition.topEnd(top: -7, end: -12),
badgeContent: null,
child: Image.asset(
leadPath,
height: ScreenUtil().setHeight(78),
fit: BoxFit.fitHeight,
),
)
: Image.asset(
leadPath,
height: ScreenUtil().setHeight(78),
fit: BoxFit.fitHeight,
),
title: new Text(title, style: TextStyle(fontSize: size)),
trailing: new Icon(Icons.arrow_forward_ios),
contentPadding: EdgeInsets.symmetric(horizontal: 20.0, vertical: 0),
enabled: true,
onTap: onTapFun,
onLongPress: onLongPressFun,
),
Divider(
height: 1.0,
),
],
);
}
List<Widget> _listViewUser = [];
List<Widget> _listViewUser_user = [];
Color _greenColor = Color.fromRGBO(36, 206, 192, 1); //绿色
Color _deepBlueColor = Color.fromRGBO(79, 118, 230, 1); //深蓝
Color _deepGreyColor = Color.fromRGBO(116, 139, 161, 1); //深灰
Color _ligthBlueColor = Color.fromRGBO(80, 159, 245, 1); //亮蓝
Future getListView() async {
_listViewUser_user.clear();
// _listViewUser.add(_getListTile('个人资料',
// leadPath: 'assets/images/我的.png',
// leadColor: _ligthBlueColor,
// onTapFun: OnTap_personal_data));
// _listViewUser.add(_getListTile('意见反馈',
// leadPath: 'assets/images/意见反馈.png',
// leadColor: _ligthBlueColor,
// onTapFun: OnTap_MyFeedback));
// _listViewUser.add(_getListTile('版本更新',
// leadPath: 'assets/images/版本更新.png', leadColor: _greenColor, onTapFun: OnTap_MyUpdate));
// _listViewUser.add(_getListTile('清除缓存',
// leadPath: 'assets/images/清除缓存.png',
// leadColor: _deepBlueColor,
// onTapFun: OnTap_ClearCache));
// _listViewUser.add(_getListTile('关于',
// leadPath: 'assets/images/关于.png', leadColor: _deepBlueColor, onTapFun: OnTap_MyAbout));
_listViewUser_user = [
_getListTile('清除缓存',
leadPath: 'assets/images/清除缓存.png',
leadColor: _deepBlueColor,
onTapFun: OnTap_ClearCache),
//用户资料修改、版本更新、意见反馈都需要后台支持才行,现在后台都没有提供支持,标书里面也没有要求,建议先去掉
// _getListTile('个人资料',
// leadPath: 'assets/images/我的.png',
// leadColor: _ligthBlueColor,
// onTapFun: OnTap_personal_data),
// _getListTile('意见反馈',
// leadPath: 'assets/images/意见反馈.png',
// leadColor: _ligthBlueColor,
// onTapFun: OnTap_MyFeedback),
_getListTile('修改密码',
leadPath: 'assets/images/修改密码.png',
leadColor: _deepBlueColor,
onTapFun: OnTap_modify_password),
//bNewVer:是否发现新版本
_getListTile('版本更新',
leadPath: 'assets/images/版本更新.png',
leadColor: _greenColor,
onTapFun: OnTap_MyUpdate,
bBadge: bNewVer),
// _getListTile('关于',
// leadPath: 'assets/images/关于.png', leadColor: _deepBlueColor, onTapFun: OnTap_MyAbout),
// _getListTile('权限测试',
// leadPath: 'assets/images/权限.png',
// leadColor: _deepGreyColor,
// onTapFun: OnTap_UserAuthority),
];
}
//已添加管理员记录的标志,0 未添加, 1 已添加 1 次
//该标志也作为是否是管理员的标志,若为 0 便不是、只是当前还不是, 1 则是管理员
//int alreadyFlag = 0;
Future getAdminItem() async {
_listViewUser.addAll(_listViewUser_user);
for (int group_id in g_userInfo.userGroupIDlist) {
print('group_id = $group_id');
if (26 == group_id || 31 == group_id) {
Widget _item = _getListTile('人脸注册',
leadPath: 'assets/images/人脸注册.png',
leadColor: _ligthBlueColor,
onTapFun: OnTap_FaceReg);
print('_listViewUser.length = ${_listViewUser.length}');
_listViewUser.add(_item);
break; //添加后便跳出循环,避免重复添加
}
}
_listViewUser.add(_getListTile('关于',
leadPath: 'assets/images/关于.png', leadColor: _deepBlueColor, onTapFun: OnTap_MyAbout));
print('_listViewUser.length = ${_listViewUser.length}');
Future.delayed(Duration(milliseconds: 500), () {
try_setState();
});
}
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(244, 244, 244, 1), //设置背景色
),
child: Column(
children: <Widget>[
Container(
height: ScreenUtil().setHeight(484), //530 - 46
child: Stack(
children: [
//1、第1行文字
Positioned(
child: Container(
height: ScreenUtil().setHeight(324), //181
alignment: Alignment.topCenter,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Color.fromRGBO(12, 186, 156, 1),
Color.fromRGBO(39, 127, 235, 1),
],
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
//crossAxisAlignment: CrossAxisAlignment.start, //用的比较少
children: <Widget>[
FlatButton(
child: Container(
child: Row(
children: [
Padding(
padding: EdgeInsets.only(top: ScreenUtil().setHeight(10)),
child: Image.asset(
'assets/images/形状 2.png',
height: ScreenUtil().setHeight(45),
),
),
Text(" 客服热线",
style: TextStyle(fontSize: 16, color: Colors.white)),
],
),
),
onPressed: () => launch("tel://18784678300"),
),
SizedBox(
width: ScreenUtil().setWidth(45),
),
Expanded(
child: Text(widget.title,
style: TextStyle(fontSize: 20.0, color: Colors.white)),
),
],
),
),
),
//2、第2行装饰
Align(
alignment: Alignment.bottomLeft,
child: Container(
alignment: Alignment(0, 1),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
//crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
padding: EdgeInsets.only(bottom: ScreenUtil().setHeight(18)),
height: ScreenUtil().setHeight(310),
decoration: BoxDecoration(
color: Color.fromRGBO(62, 88, 231, 1),
borderRadius: BorderRadius.horizontal(right: Radius.circular(20)),
),
//color: Colors.pinkAccent,
width: ScreenUtil().setWidth(34),
alignment: Alignment.centerRight,
),
getImageWidget(),
// Container(
// alignment: Alignment(0, 0),
// height: ScreenUtil().setHeight(346),
// width: ScreenUtil().setWidth(942),
// child: Image.asset(
// 'assets/images/装饰图片10.png',
// fit: BoxFit.cover,
// ),
// ),
Container(
height: ScreenUtil().setHeight(310),
decoration: BoxDecoration(
color: Color.fromRGBO(113, 39, 203, 1),
borderRadius: BorderRadius.horizontal(left: Radius.circular(20)),
),
//color: Colors.pinkAccent,
width: ScreenUtil().setWidth(34),
alignment: Alignment.centerRight,
),
],
),
),
),
],
),
),
//3、第3行统计信息
SizedBox(height: ScreenUtil().setHeight(46)),
Expanded(
//Flutter Column套ListView不显示,可将ListView用Expanded包裹起来。
//用 ListView.builder 不好区别处理响应函数的动态参数传递,所以使用基本 ListView
// child: ListView.builder(
// itemCount: listContacts.length,
// itemBuilder: this._getlistContacts),
child: _listViewUser.isEmpty
? getMoreWidget(color: Colors.black26)
: ListView(
padding: EdgeInsets.all(10),
children: _listViewUser,
),
),
Divider(
height: 20.0,
indent: 0.0,
thickness: 1.0,
color: Color.fromRGBO(80, 159, 245, 1),
),
// Center(
// child: RaisedButton(
// //padding: EdgeInsets.all(0),
// onPressed: () {
// Navigator.pushNamed(context, '/', arguments: 0);
// },
// //color: Colors.transparent,
// child: Text('退出登录'),
// ),
// ),
JdButton(
height: 126,
//JdText中已经使用ScreenUtil().setHeight(126),此处不能传 ScreenUtil().setHeight(126) ,否则严重错位
width: 350,
text: "退出登录",
color: Color.fromRGBO(80, 159, 245, 1),
onTop: () {
Navigator.pushNamed(context, '/', arguments: 0);
},
),
SizedBox(
height: 20.0, //防止误触,所以设大一些
),
],
),
),
onWillPop: () {
sysPop();
},
);
}
OnTap_MyAbout() {
PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
String buildDate =
'${buildNumber.substring(0, 4)}.${buildNumber.substring(4, 6)}.${buildNumber.substring(6, 8)}';
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => MyAbout(ver: version, date: buildDate)));
});
}
OnTap_MyUpdate() {
PackageInfo.fromPlatform().then((PackageInfo packageInfo) async {
String appName = packageInfo.appName;
String packageName = packageInfo.packageName;
String version = packageInfo.version;
String buildNumber = packageInfo.buildNumber;
String buildDate =
'${buildNumber.substring(0, 4)}.${buildNumber.substring(4, 6)}.${buildNumber.substring(6, 8)}';
print('appName = $appName');
print('packageName = $packageName');
print('version = $version');
print('buildNumber = $buildNumber');
print('buildDate = $buildDate');
// I/flutter (30820): appName = 宜宾黑烟抓拍
// I/flutter (30820): packageName = com.flutter.hyzp_ybqx
// I/flutter (30820): version = 1.3.1
// I/flutter (30820): buildNumber = 20210508
// I/flutter (30820): buildDate = 2021.05.08
//Fluttertoast.showToast(msg: '当前版本 v$version。暂无更新', gravity: ToastGravity.CENTER);
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => MyUpdated(ver: version, date: buildDate, theContext: context)));
MyUpdatedNew m = await MyUpdatedNew(
ver: version,
date: buildDate,
theContext: context,
bStartUpdated: true,
bShowNoNewVersion: true);
});
}
Future _getTotalSizeOfFilesInDir(final FileSystemEntity file) async {
if (file is File) {
int length = await file.length();
return double.parse(length.toString());
}
if (file is Directory) {
final List children = file.listSync();
double total = 0;
if (children != null)
for (final FileSystemEntity child in children)
total += await _getTotalSizeOfFilesInDir(child);
return total;
}
return 0;
}
OnTap_FaceLogin() async {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => FaceLogin()));
}
OnTap_FaceReg() async {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => FaceReg()));
}
OnTap_modify_password() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => ModifyPassword()));
}
OnTap_personal_data() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => PersonalData()));
}
OnTap_MyFeedback() {
Navigator.of(context).push(MaterialPageRoute(builder: (context) => MyFeedback()));
}
OnTap_UserAuthority() async {
//1、根据用户ID获取用户所属角色(用户组)
//getUserAccess(user_id: 136);
//2.2、获取后台用户全部角色分组数据
//I/flutter (15540): g_userInfo.userGroupIDlist = [32, 33]
// g_userInfo.userRulesMap.clear();
// //getUserGroup(group_id: 27);
// getUserGroupAll(user_id: 136);
//
// Future.delayed(const Duration(milliseconds: 3500), () {
// print('g_userInfo.userRulesMap = ${g_userInfo.userRulesMap.toString()}');
// });
//I/flutter (15540): g_userInfo.userRulesMap = {32: [1968, 1972, 1973, 1969, 1976, 1977, 2008, 2009, 2011, 2014, 2015, 2018, 2029, 2030, 2031, 2054, 2055, 2035, 2036, 2037, 204
// 1, 2042, 2043, 2047, 2048, 2049, 2053, 1970, 1980, 1981, 1971, 1984, 1985, 1992, 1993, 2000, 2001, 2020, 2022], 33: [1968, 1972, 1973, 1969, 1976, 1977, 2008, 2009, 2011, 201
// 4, 2015, 2018, 2029, 2030, 2031, 2054, 2055, 2035, 2036, 2037, 2041, 2042, 2043, 2047, 2048, 2049, 2053, 1970, 1980, 1981, 1971, 1984, 1985, 1992, 1993, 2000, 2001, 2019, 202
// 0, 2022]}
// getUserGroup(group_id: g_userInfo.userGroupIDlist[0]);
// print('g_userInfo.userRulesMap = ${g_userInfo.userRulesMap.toString()}');
//I/flutter (15540): g_userInfo.userRulesMap = {32: [1968, 1972, 1973, 1969, 1976, 1977, 2008, 2009, 2011,
// 2014, 2015, 2018, 2029, 2030, 2031, 2054, 2055, 2035, 2036, 2037, 2041, 2042, 2043, 2047,
// 2048, 2049, 2053, 1970, 1980, 1981, 1971, 1984, 1985, 1992, 1993, 2000, 2001, 2020, 2022]}
// g_userInfo.userRulesMap.clear();
// getUserGroupAll();
// print('g_userInfo.userGroupIDlist = ${g_userInfo.userGroupIDlist}');
// print('g_userInfo.userGroupIDlist[0] = ${g_userInfo.userGroupIDlist[0]}');
// getUserGroup(group_id: g_userInfo.userGroupIDlist[0]);
//I/flutter (15540): g_userInfo.userGroupIDlist = [31, 27]
//getUserGroup(group_id: g_userInfo.userGroupIDlist[1]);
///3、获取后台全部 (All) 用户角色分组分页列表数据
// getRecordList(api: ServicePath.getUserGroupListUrl).then((map) {
// mapUserGroupList = map;
// });
//I/flutter ( 1422): http://125.64.218.67:9904/?s=App.User_User.GetGroupList
// I/flutter ( 1422): 开始处理登录请求...
// I/flutter ( 1422): response = {"ret":200,"data":{"items":[{"id":35,"jgid":2,"type":0,"title":"局领导","level":0,"pid":0,"sort":1,"status":1,"rules":""},{"id":34,"jgid":2,"typ
// e":0,"title":"系统管理","level":0,"pid":0,"sort":1,"status":1,"rules":""},{"id":33,"jgid":2,"type":1,"title":"参观者","level":0,"pid":0,"sort":4,"status":1,"rules":"1968,1972
// ,1973,1969,1976,1977,2008,2009,2011,2014,2015,2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,200
// 1,2019,2020,2022"},{"id":32,"jgid":2,"type":0,"title":"演示账户","level":0,"pid":0,"sort":3,"status":1,"rules":"1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,2015,2018,20
// 29,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2020,2022"},{"id":31,"jgid":2,"type":0,"title":"监
// 控室","level":0,"pid":0,"sort":2,"status":1,"rules":""},{"id":30,"jgid":2,"type":0,"title":"中心领导","level":0,"pid":0,"sort":1,"status":1,"rules":"196
// I/flutter ( 1422): mapRecordList['mapRecordListRet'] = {ret: 200, data: {items: [{id: 35, jgid: 2, type: 0, title: 局领导, level: 0, pid: 0, sort: 1, status: 1, rules: }, {id
// : 34, jgid: 2, type: 0, title: 系统管理, level: 0, pid: 0, sort: 1, status: 1, rules: }, {id: 33, jgid: 2, type: 1, title: 参观者, level: 0, pid: 0, sort: 4, status: 1, rules
// : 1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,2015,2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,19
// 93,2000,2001,2019,2020,2022}, {id: 32, jgid: 2, type: 0, title: 演示账户, level: 0, pid: 0, sort: 3, status: 1, rules: 1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,2015,
// 2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2020,2022}, {id: 31, jgid: 2, type: 0, title
// : 监控室, level: 0, pid: 0, sort: 2, status: 1, rules: }, {id: 30, jgid: 2, type: 0, title: 中心领导, level: 0, pid: 0, sort: 1, status: 1, rules: 1968
// I/flutter ( 1422): mapRecordList['listRecordList'] = []
// I/flutter ( 1422): _list1 = [{id: 35, jgid: 2, type: 0, title: 局领导, level: 0, pid: 0, sort: 1, status: 1, rules: }, {id: 34, jgid: 2, type: 0, title: 系统管理, level: 0, p
// id: 0, sort: 1, status: 1, rules: }, {id: 33, jgid: 2, type: 1, title: 参观者, level: 0, pid: 0, sort: 4, status: 1, rules: 1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,
// 2015,2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2019,2020,2022}, {id: 32, jgid: 2, type
// : 0, title: 演示账户, level: 0, pid: 0, sort: 3, status: 1, rules: 1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,2015,2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,20
// 42,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2020,2022}, {id: 31, jgid: 2, type: 0, title: 监控室, level: 0, pid: 0, sort: 2, status: 1, rule
// s: }, {id: 30, jgid: 2, type: 0, title: 中心领导, level: 0, pid: 0, sort: 1, status: 1, rules: 1968,1972,1973,1974,1975,1969,1976,1977,1978,1979,1970,1
// I/flutter ( 1422): mapRecordList['listRecordList'] = [{id: 35, jgid: 2, type: 0, title: 局领导, level: 0, pid: 0, sort: 1, status: 1, rules: }, {id: 34, jgid: 2, type: 0, tit
// le: 系统管理, level: 0, pid: 0, sort: 1, status: 1, rules: }, {id: 33, jgid: 2, type: 1, title: 参观者, level: 0, pid: 0, sort: 4, status: 1, rules: 1968,1972,1973,1969,1976,
// 1977,2008,2009,2011,2014,2015,2018,2029,2030,2031,2054,2055,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2019,2020,2022
// }, {id: 32, jgid: 2, type: 0, title: 演示账户, level: 0, pid: 0, sort: 3, status: 1, rules: 1968,1972,1973,1969,1976,1977,2008,2009,2011,2014,2015,2018,2029,2030,2031,2054,20
// 55,2035,2036,2037,2041,2042,2043,2047,2048,2049,2053,1970,1980,1981,1971,1984,1985,1992,1993,2000,2001,2020,2022}, {id: 31, jgid: 2, type: 0, title: 监控室, level: 0, pid: 0,
// sort: 2, status: 1, rules: }, {id: 30, jgid: 2, type: 0, title: 中心领导, level: 0, pid: 0, sort: 1, status: 1, rules: 1968,1972,1973,1974,1975,1969,1
// I/flutter ( 1422): map['page'] = 1
// I/flutter ( 1422): _counter = 8
// I/flutter ( 1422): _total = 8
///5、获取后台功能分类分页列表数据
// getRecordList(api: ServicePath.getUserAuthListUrl).then((map) {
// mapUserAuthList = map;
// });
//I/flutter ( 3512): http://125.64.218.67:9904/?s=App.User_User.GetAuthList
// I/flutter ( 3512): 开始处理登录请求...
// I/flutter ( 3512): response = {"ret":200,"data":{"items":[{"id":2069,"jgid":2,"level":2,"pid":2067,"name":"blacksmoke2/b2tj/fenxicll/fenxi","title":"分析","type":1,"status":1
// ,"condition":"","sort":9},{"id":2068,"jgid":2,"level":2,"pid":2067,"name":"blacksmoke2/b2tj/fenxicll/view","title":"查看","type":1,"status":1,"condition":"","sort":0},{"id":2
// 067,"jgid":2,"level":1,"pid":2029,"name":"blacksmoke2/b2tj/fenxicll","title":"车流量统计","type":1,"status":1,"condition":"","sort":7},{"id":2066,"jgid":2,"level":2,"pid":206
// 4,"name":"blacksmoke2/b2tj/dwinfoview/fenxi","title":"分析","type":1,"status":1,"condition":"","sort":9},{"id":2065,"jgid":2,"level":2,"pid":2064,"name":"blacksmoke2/b2tj/dwi
// nfoview/view","title":"查看","type":1,"status":1,"condition":"","sort":0},{"id":2064,"jgid":2,"level":1,"pid":2029,"name":"blacksmoke2/b2tj/dwinfoview","title":"监测点位状态
// 详情","type":1,"status":1,"condition":"","sort":6},{"id":2063,"jgid":2,"level":2,"pid":2061,"name":"blacksmoke2/b2tj/dwinfo/fenxi","title":"分析","typ
// I/flutter ( 3512): mapRecordList['mapRecordListRet'] = {ret: 200, data: {items: [{id: 2069, jgid: 2, level: 2, pid: 2067, name: blacksmoke2/b2tj/fenxicll/fenxi, title: 分析,
// type: 1, status: 1, condition: , sort: 9}, {id: 2068, jgid: 2, level: 2, pid: 2067, name: blacksmoke2/b2tj/fenxicll/view, title: 查看, type: 1, status: 1, condition: , sort:
// 0}, {id: 2067, jgid: 2, level: 1, pid: 2029, name: blacksmoke2/b2tj/fenxicll, title: 车流量统计, type: 1, status: 1, condition: , sort: 7}, {id: 2066, jgid: 2, level: 2, pid:
// 2064, name: blacksmoke2/b2tj/dwinfoview/fenxi, title: 分析, type: 1, status: 1, condition: , sort: 9}, {id: 2065, jgid: 2, level: 2, pid: 2064, name: blacksmoke2/b2tj/dwinfo
// view/view, title: 查看, type: 1, status: 1, condition: , sort: 0}, {id: 2064, jgid: 2, level: 1, pid: 2029, name: blacksmoke2/b2tj/dwinfoview, title: 监测点位状态详情, type:
// 1, status: 1, condition: , sort: 6}, {id: 2063, jgid: 2, level: 2, pid: 2061, name: blacksmoke2/b2tj/dwinfo/fenxi, title: 分析, type: 1, status: 1, c
// I/flutter ( 3512): map['page'] = 1
// I/flutter ( 3512): _counter = 20
// I/flutter ( 3512): _total = 78
// I/flutter ( 3512): 第 1 次网络请求过程正常完成
// I/flutter ( 3512): response = {"ret":200,"data":{"items":[{"id":2042,"jgid":2,"level":1,"pid":2029,"name":"blacksmoke2/b2tj/fenxicartime","title":"车辆轨迹查询","type":1,"sta
// tus":1,"condition":"","sort":3},{"id":2041,"jgid":2,"level":2,"pid":2036,"name":"blacksmoke2/b2tj/fenxicar/fenxi","title":"分析","type":1,"status":1,"condition":"","sort":9},
// {"id":2037,"jgid":2,"level":2,"pid":2036,"name":"blacksmoke2/b2tj/fenxicar/view","title":"查看","type":1,"status":1,"condition":"","sort":0},{"id":2036,"jgid":2,"level":1,"pi
// d":2029,"name":"blacksmoke2/b2tj/fenxicar","title":"车辆点位频率分析","type":1,"status":1,"condition":"","sort":2},{"id":2035,"jgid":2,"level":2,"pid":2030,"name":"blacksmoke
// 2/b2tj/fenxi","title":"分析","type":1,"status":1,"condition":"","sort":9},{"id":2034,"jgid":2,"level":2,"pid":2030,"name":"blacksmoke2/b2tj/outxls","title":"导出","type":1,"s
// tatus":1,"condition":"","sort":7},{"id":2031,"jgid":2,"level":2,"pid":2030,"name":"blacksmoke2/b2tj/view","title":"查看","type":1,"status":1,"condit
// I/flutter ( 3512): mapRecordList['mapRecordListRet'] = {ret: 200, data: {items: [{id: 2042, jgid: 2, level: 1, pid: 2029, name: blacksmoke2/b2tj/fenxicartime, title: 车辆轨迹
// 查询, type: 1, status: 1, condition: , sort: 3}, {id: 2041, jgid: 2, level: 2, pid: 2036, name: blacksmoke2/b2tj/fenxicar/fenxi, title: 分析, type: 1, status: 1, condition: ,
// sort: 9}, {id: 2037, jgid: 2, level: 2, pid: 2036, name: blacksmoke2/b2tj/fenxicar/view, title: 查看, type: 1, status: 1, condition: , sort: 0}, {id: 2036, jgid: 2, level: 1
// , pid: 2029, name: blacksmoke2/b2tj/fenxicar, title: 车辆点位频率分析, type: 1, status: 1, condition: , sort: 2}, {id: 2035, jgid: 2, level: 2, pid: 2030, name: blacksmoke2/b
// 2tj/fenxi, title: 分析, type: 1, status: 1, condition: , sort: 9}, {id: 2034, jgid: 2, level: 2, pid: 2030, name: blacksmoke2/b2tj/outxls, title: 导出, type: 1, status: 1, co
// ndition: , sort: 7}, {id: 2031, jgid: 2, level: 2, pid: 2030, name: blacksmoke2/b2tj/view, title: 查看, type: 1, status: 1, condition: , sort: 0}, {
// I/flutter ( 3512): map['page'] = 2
// I/flutter ( 3512): _counter = 40
// I/flutter ( 3512): _total = 78
// I/flutter ( 3512): 第 2 次网络请求过程正常完成
// I/flutter ( 3512): response = {"ret":200,"data":{"items":[{"id":2008,"jgid":2,"level":1,"pid":1969,"name":"blacksmoke2/b2yjfsls/index","title":"历史数据","type":1,"status":1,
// "condition":"","sort":2},{"id":2007,"jgid":2,"level":2,"pid":2000,"name":"blacksmoke2/b2dwinfo/inxls","title":"导入","type":1,"status":1,"condition":"","sort":8},{"id":2006,"
// jgid":2,"level":2,"pid":2000,"name":"blacksmoke2/b2dwinfo/outxls","title":"导出","type":1,"status":1,"condition":"","sort":7},{"id":2005,"jgid":2,"level":2,"pid":2000,"name":
// "blacksmoke2/b2dwinfo/del","title":"删除","type":1,"status":1,"condition":"","sort":4},{"id":2004,"jgid":2,"level":2,"pid":2000,"name":"blacksmoke2/b2dwinfo/lock","title":"锁
// 定","type":1,"status":1,"condition":"","sort":3},{"id":2003,"jgid":2,"level":2,"pid":2000,"name":"blacksmoke2/b2dwinfo/edit","title":"编辑","type":1,"status":1,"condition":""
// ,"sort":2},{"id":2002,"jgid":2,"level":2,"pid":2000,"name":"blacksmoke2/b2dwinfo/add","title":"新增","type":1,"status":1,"condition":"","sort":1},{"id":2001
// I/flutter ( 3512): mapRecordList['mapRecordListRet'] = {ret: 200, data: {items: [{id: 2008, jgid: 2, level: 1, pid: 1969, name: blacksmoke2/b2yjfsls/index, title: 历史数据, t
// ype: 1, status: 1, condition: , sort: 2}, {id: 2007, jgid: 2, level: 2, pid: 2000, name: blacksmoke2/b2dwinfo/inxls, title: 导入, type: 1, status: 1, condition: , sort: 8}, {
// id: 2006, jgid: 2, level: 2, pid: 2000, name: blacksmoke2/b2dwinfo/outxls, title: 导出, type: 1, status: 1, condition: , sort: 7}, {id: 2005, jgid: 2, level: 2, pid: 2000, na
// me: blacksmoke2/b2dwinfo/del, title: 删除, type: 1, status: 1, condition: , sort: 4}, {id: 2004, jgid: 2, level: 2, pid: 2000, name: blacksmoke2/b2dwinfo/lock, title: 锁定, t
// ype: 1, status: 1, condition: , sort: 3}, {id: 2003, jgid: 2, level: 2, pid: 2000, name: blacksmoke2/b2dwinfo/edit, title: 编辑, type: 1, status: 1, condition: , sort: 2}, {i
// d: 2002, jgid: 2, level: 2, pid: 2000, name: blacksmoke2/b2dwinfo/add, title: 新增, type: 1, status: 1, condition: , sort: 1}, {id: 2001, jgid: 2, level: 2,
// I/flutter ( 3512): map['page'] = 3
// I/flutter ( 3512): _counter = 60
// I/flutter ( 3512): _total = 78
// I/flutter ( 3512): 第 3 次网络请求过程正常完成
// I/flutter ( 3512): response = {"ret":200,"data":{"items":[{"id":1988,"jgid":2,"level":2,"pid":1984,"name":"blacksmoke2/b2ledxs/lock","title":"锁定","type":1,"status":1,"condi
// tion":"","sort":3},{"id":1987,"jgid":2,"level":2,"pid":1984,"name":"blacksmoke2/b2ledxs/edit","title":"编辑","type":1,"status":1,"condition":"","sort":2},{"id":1986,"jgid":2,
// "level":2,"pid":1984,"name":"blacksmoke2/b2ledxs/add","title":"新增","type":1,"status":1,"condition":"","sort":1},{"id":1985,"jgid":2,"level":2,"pid":1984,"name":"blacksmoke2
// /b2ledxs/view","title":"查看","type":1,"status":1,"condition":"","sort":0},{"id":1984,"jgid":2,"level":1,"pid":1971,"name":"blacksmoke2/b2ledxs/index","title":"LED显示设置","
// type":1,"status":1,"condition":"","sort":1},{"id":1983,"jgid":2,"level":2,"pid":1980,"name":"blacksmoke2/b2ts/shenhe","title":"审核","type":1,"status":1,"condition":"","sort"
// :5},{"id":1981,"jgid":2,"level":2,"pid":1980,"name":"blacksmoke2/b2ts/view","title":"查看","type":1,"status":1,"condition":"","sort":0},{"id":1980,"jgid":2,
// I/flutter ( 3512): mapRecordList['mapRecordListRet'] = {ret: 200, data: {items: [{id: 1988, jgid: 2, level: 2, pid: 1984, name: blacksmoke2/b2ledxs/lock, title: 锁定, type: 1
// , status: 1, condition: , sort: 3}, {id: 1987, jgid: 2, level: 2, pid: 1984, name: blacksmoke2/b2ledxs/edit, title: 编辑, type: 1, status: 1, condition: , sort: 2}, {id: 1986
// , jgid: 2, level: 2, pid: 1984, name: blacksmoke2/b2ledxs/add, title: 新增, type: 1, status: 1, condition: , sort: 1}, {id: 1985, jgid: 2, level: 2, pid: 1984, name: blacksmo
// ke2/b2ledxs/view, title: 查看, type: 1, status: 1, condition: , sort: 0}, {id: 1984, jgid: 2, level: 1, pid: 1971, name: blacksmoke2/b2ledxs/index, title: LED显示设置, type:
// 1, status: 1, condition: , sort: 1}, {id: 1983, jgid: 2, level: 2, pid: 1980, name: blacksmoke2/b2ts/shenhe, title: 审核, type: 1, status: 1, condition: , sort: 5}, {id: 1981
// , jgid: 2, level: 2, pid: 1980, name: blacksmoke2/b2ts/view, title: 查看, type: 1, status: 1, condition: , sort: 0}, {id: 1980, jgid: 2, level: 1, pid: 1970
// I/flutter ( 3512): map['page'] = 4
// I/flutter ( 3512): _counter = 78
// I/flutter ( 3512): _total = 78
///6、获取后台功能分类分页列表数据,然后获取用户功能权限索引map,便于直观理解和处理
// getRecordList(api: ServicePath.getUserAuthListUrl).then((map) {
// mapUserAuthList = map;
// getUserAuth();
// });
///7、获取后台功能分类分页列表数据,然后获取用户功能路径索引map,便于直观理解和处理
// getRecordList(api: ServicePath.getUserAuthListUrl).then((map) {
// mapUserAuthList = map;
// getUserAuthMap(value: 'name');
// });
///8、测试新的视频地址 rtsp://125.64.218.67:9901/rtp/gb_play_34020000001320013016_34020000001320013016
// urlnew = 'rtsp://125.64.218.67:9901/rtp/gb_play_34020000001320013016_34020000001320013016';
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => PlayerPro(
// url: urlnew,
// title: '点位视频测试',
// )));
///9、测试新的视频地址 rtmp://125.64.218.67:9901/rtp/gb_play_34020000001320013016_34020000001320013016
// urlnew = 'rtmp://125.64.218.67:9901/rtp/gb_play_34020000001320013016_34020000001320013016';
// Navigator.of(context).push(MaterialPageRoute(
// builder: (context) => PlayerPro(
// url: urlnew,
// title: '点位视频测试',
// )));
// getRecordList(api: ServicePath.getUserAuthListUrl).then((map) {
// mapUserAuthList = map;
// // var _jsonStr = json.encode(getUserAuthMap(value: 'name'));
// // List _list = json.decode(_jsonStr);
//
// Map<String, dynamic> map1 = {"name": "AllenSu", "area": "郑州", "sex": "男", "age": 18};
// String _jsonStr = json.encode(map1);
// //print('_jsonStr = $_jsonStr');
// //List _list = json.decode(_jsonStr);
// // Unhandled Exception: type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'
// Map map2 = json.decode(_jsonStr);
// //print('_list = ${_list}');
//
// String str = json_print(map2, 1);
// List list = ['test', 'dsaf', 'swer'];
// //segmentPrint(str);
// //print('_jsonStr = ${json_print(map2, 1)}');
//
// print('str = ${str}');
// my_segmentPrint(str);
//
// });
}
Future<Null> loadCache() async {
Directory tempDir = await getTemporaryDirectory();
double value = await _getTotalSizeOfFilesInDir(tempDir);
print('临时目录大小: ' + value.toString());
//清除缓存
delDir(tempDir);
}
//递归方式删除目录
Future<Null> delDir(FileSystemEntity file) async {
if (file is Directory) {
final List<FileSystemEntity> children = file.listSync();
for (final FileSystemEntity child in children) {
await delDir(child);
}
}
await file.delete();
}
OnTap_ClearCache() async {
Directory tempDir = await getTemporaryDirectory();
print('tempDir: ' + tempDir.path);
double SizeOfFiles = await _getTotalSizeOfFilesInDir(tempDir) / 1000000;
print('临时目录大小: ${SizeOfFiles.toString()} MB');
bool ret = await showDialog(
context: context,
builder: (context) {
myController.text = '';
return CustomDialogF(
title: "选择操作",
content: '缓存大小:${SizeOfFiles.toString()} MB,是否清除',
);
});
print('ret: $ret');
if (ret) {
print('清除缓存...');
//清除内存
PaintingBinding.instance.imageCache.clear();
//清除缓存
delDir(tempDir);
//清空SharedPreferences
Storage.clear();
}
}
}
+66
View File
@@ -0,0 +1,66 @@
import 'package:flutter/material.dart';
import '../../custom_icons/icons_data.dart';
import '../../custom_icons/icons_name.dart';
class DetailsPage extends StatelessWidget {
final String arguments; //id of icon
DetailsPage({Key key, this.arguments = 'text'}) : super(key: key);
@override
Widget build(BuildContext context) {
String s = '图标ID :$arguments' + '\n图标名称:' + iconNameList[int.parse(arguments)];
return Scaffold(
appBar: AppBar(
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
print('返回上一页');
Navigator.pop(context);
},
),
title: Text('联系人详情页'),
),
body: FutureBuilder(
future: null,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Stack(
children: <Widget>[
ListView(
children: <Widget>[
Text(arguments),
],
),
Positioned(
bottom: 0,
left: 0,
child: null,
)
],
);
} else {
//return Text('加载中........');
return Container(
alignment: Alignment(0, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
iconList[int.parse(arguments)],
size: 200,
color: Colors.black,
),
SizedBox(height: 10,),
Text(s),
],
),
);
}
},
),
);
}
}