hyzp_ybqx-Commit001:代码刚转换好,编译通过
This commit is contained in:
@@ -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));
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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];
|
||||
}
|
||||
}
|
||||
@@ -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(); //避免如下异常报错
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user