hyzp_ybqx-Commit001:代码刚转换好,编译通过
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/screen_util.dart';
|
||||
import '../components/hyxx_data_handle.dart';
|
||||
import '../services/EventBus.dart';
|
||||
|
||||
class CarNumberAndCpysItems extends StatefulWidget {
|
||||
int index;
|
||||
String initValue;
|
||||
|
||||
CarNumberAndCpysItems(
|
||||
this.index, this.initValue); //I don't know what is this index for but I will put it in anyway
|
||||
@override
|
||||
_CarNumberAndCpysItemsState createState() => _CarNumberAndCpysItemsState();
|
||||
}
|
||||
|
||||
class _CarNumberAndCpysItemsState extends State<CarNumberAndCpysItems> {
|
||||
List<DropdownMenuItem<String>> _dropDownMenuItems;
|
||||
String selectedValue;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
selectedValue = widget.initValue;
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
}
|
||||
|
||||
List<DropdownMenuItem<String>> getDropDownMenuItems() {
|
||||
List<DropdownMenuItem<String>> items = [];
|
||||
int len = cpysList.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
items.add(
|
||||
DropdownMenuItem(
|
||||
value: cpysList[i].cpysText,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
cpysList[i].cpysText,
|
||||
style: TextStyle(
|
||||
color: cpysList[i].cpysFont,
|
||||
background: Paint()..color = cpysList[i].cpysBackground),
|
||||
),
|
||||
(selectedValue == cpysList[i].cpysText)
|
||||
? Icon(
|
||||
Icons.check,
|
||||
//color: cpysList[i].cpysBackground,
|
||||
size: 16,
|
||||
)
|
||||
: SizedBox(
|
||||
width: 0,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
Widget getDropdownButton() {
|
||||
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
|
||||
//更改图标亮度
|
||||
return Theme(
|
||||
//data: Theme.of(context).copyWith(primaryColor: cpysList[getIndexOfCpysList(colorText: selectedValue)].cpysFont),
|
||||
data: Theme.of(context).copyWith(brightness: Brightness.dark),
|
||||
child: DropdownButtonHideUnderline(
|
||||
child: DropdownButton(
|
||||
iconEnabledColor: cpysList[getIndexOfCpysList(colorText: selectedValue)].cpysFont,
|
||||
value: selectedValue,
|
||||
items: _dropDownMenuItems,
|
||||
onChanged: (String _selectedFruit) {
|
||||
selectedValue = _selectedFruit;
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
//黑烟初审数据审核Dropdown选项改变广播
|
||||
eventBus.fire(HycsDataAuditDropdownEvent('黑烟初审数据审核Dropdown选项已改变', selectedValue));
|
||||
setState(() {});
|
||||
print('selectedValue = $selectedValue');
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
//Tab页面中的车牌号码、车牌颜色组件
|
||||
Widget getCarNumberAndCpys(int i) {
|
||||
return Container(
|
||||
width: ScreenUtil().setWidth(1022),
|
||||
height: ScreenUtil().setHeight(my_listTileHeight2 * 2 + 15),
|
||||
child: Column(children: [
|
||||
//1、车牌号码
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
SizedBox(width: ScreenUtil().setWidth(my_marginLeft2)),
|
||||
Text('${mapGetZpjlGetDataSpecial['car_number'].fieldText}: ',
|
||||
style: TextStyle(fontSize: my_fontSize)),
|
||||
Container(
|
||||
alignment: Alignment(-1, 0),
|
||||
//widthTrail = 400报错,360刚能显示,300换行,260
|
||||
height: ScreenUtil().setHeight(my_listTileHeight2), //最大高度
|
||||
width: ScreenUtil().setWidth(400),
|
||||
child: TextField(
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: my_fontSize,
|
||||
//color: cpysList[getIndexOfCpysList(colorText: listGetZpjl[i]['cpys'])].cpysFont,
|
||||
//color: cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])].cpysFont,
|
||||
color: cpysList[getIndexOfCpysList(colorText: selectedValue)].cpysFont,
|
||||
),
|
||||
// background: Paint()
|
||||
// ..color = cpysList[getIndexOfCpysList(colorText: listGetZpjl[i]['cpys'])]
|
||||
// .cpysBackground),
|
||||
decoration: InputDecoration(
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(width: 2.0), borderRadius: BorderRadius.circular(3.0)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(width: 2.0), borderRadius: BorderRadius.circular(3.0)),
|
||||
//prefixText: "pre",
|
||||
filled: true,
|
||||
//fillColor: cpysList[getIndexOfCpysList(colorText: listGetZpjl[i]['cpys'])].cpysBackground,
|
||||
//fillColor: cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])].cpysBackground,
|
||||
fillColor: cpysList[getIndexOfCpysList(colorText: selectedValue)].cpysBackground,
|
||||
hintText: '车牌号码',
|
||||
//border: InputBorder.none, //TextField去掉下划线
|
||||
//contentPadding: EdgeInsets.only(right: 0),
|
||||
//contentPadding: const EdgeInsets.symmetric(vertical: _textFieldHeight),
|
||||
//contentPadding: EdgeInsets.symmetric(vertical: _textFieldHeight),
|
||||
contentPadding: EdgeInsets.all(0),
|
||||
//contentPadding: EdgeInsets.only(top: 0),
|
||||
|
||||
// border: OutlineInputBorder(
|
||||
// //borderRadius: BorderRadius.circular(1.0),
|
||||
// borderSide: BorderSide(
|
||||
// //color: cpysList[getIndexOfCpysList(colorText: listGetZpjl[i]['cpys'])].cpysBorder,
|
||||
// color:
|
||||
// cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])]
|
||||
// .cpysBorder,
|
||||
// width: 2.0)),
|
||||
),
|
||||
//controller: listZpljController[i][indexField],
|
||||
controller: TextEditingController.fromValue(TextEditingValue(
|
||||
text: listGetZpjl[i]['car_number'].toString(),
|
||||
// 保持光标在最后
|
||||
selection: TextSelection.fromPosition(TextPosition(
|
||||
affinity: TextAffinity.downstream,
|
||||
offset: '${listGetZpjl[i]['car_number'].toString()}'.length)))),
|
||||
enabled: true,
|
||||
//利用控制器初始化文本
|
||||
onChanged: (value) {
|
||||
listGetZpjl[i]['car_number'] = value;
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(width: ScreenUtil().setWidth(my_marginLeft2)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: ScreenUtil().setHeight(15)),
|
||||
//2、车牌颜色
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
SizedBox(width: ScreenUtil().setWidth(my_marginLeft2)),
|
||||
Text('车牌颜色: ',
|
||||
style: TextStyle(fontSize: my_fontSize)),
|
||||
Container(
|
||||
alignment: Alignment(1, 0),
|
||||
//widthTrail = 400报错,360刚能显示,300换行,260
|
||||
height: ScreenUtil().setHeight(my_listTileHeight2), //最大高度
|
||||
width: ScreenUtil().setWidth(400),
|
||||
margin: EdgeInsets.only(bottom: 0),
|
||||
padding: EdgeInsets.only(left: 0, bottom: 2),
|
||||
decoration: BoxDecoration(
|
||||
//color: cpysList[getIndexOfCpysList(colorText: listGetZpjl[i]['cpys'])].cpysBackground,
|
||||
//color: cpysList[getIndexOfCpysList(colorText: topTabs_map['cpysText_List'][i])].cpysBackground,
|
||||
color: cpysList[getIndexOfCpysList(colorText: selectedValue)].cpysBackground,
|
||||
border: Border.all(color: Colors.black87, width: 2),
|
||||
//边框圆角设置
|
||||
borderRadius: BorderRadius.vertical(
|
||||
top: Radius.elliptical(3, 3), bottom: Radius.elliptical(3, 3)),
|
||||
),
|
||||
child: getDropdownButton(),
|
||||
)
|
||||
],
|
||||
),
|
||||
],),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return getCarNumberAndCpys(widget.index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/screen_util.dart';
|
||||
import '../services/EventBus.dart';
|
||||
import '../components/dioFun.dart';
|
||||
|
||||
//错误提示
|
||||
// This class (or a class which this class inherits from) is marked as '@immutable', but one or more of
|
||||
// This class (or a class that this class inherits from) is marked as '@immutable', but one or more of
|
||||
//
|
||||
// 原本是自定义一个导航栏,需要传递一个参数(标题)过来。
|
||||
// class NavWidget extends StatelessWidget {
|
||||
// String title; //
|
||||
// NavWidget(this.title);
|
||||
// 结果就提示了上面的错误。看了下有道翻译
|
||||
// 有道翻译:这个类(或该类继承自的一个类)被标记为“@不可变”,但是它的一个或多个实例字段不是final: NavWidget.title
|
||||
// 意为StatelessWidget是一个不可变的widget,申明的title也应为不可变的。所以我就加了个申明的关键字final。然后警告就没了
|
||||
//
|
||||
// 以下是修改后的代码,不再报错
|
||||
// class NavWidget extends StatelessWidget {
|
||||
// final String title; //
|
||||
// NavWidget(this.title);
|
||||
|
||||
class CheckboxButtonItem extends StatefulWidget {
|
||||
final int index;
|
||||
|
||||
CheckboxButtonItem(this.index); //I don't know what is this index for but I will put it in anyway
|
||||
@override
|
||||
_CheckboxButtonItemState createState() => _CheckboxButtonItemState();
|
||||
}
|
||||
|
||||
class _CheckboxButtonItemState extends State<CheckboxButtonItem> {
|
||||
//try_setState(); //避免如下异常报错
|
||||
try_setState() {
|
||||
try {
|
||||
setState(() {});
|
||||
} catch (e) {
|
||||
print('setState(() {})异常:${e}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
//黑烟审核推送交警Checkbox改变事件
|
||||
eventBus.on<HycsDataAuditSfyc>().listen((event) {
|
||||
print(event.str);
|
||||
try_setState(); //避免如下异常报错
|
||||
});
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
//自定义带说明图标按钮函数。点击说明文字有反应
|
||||
Widget _getCheckboxButton() {
|
||||
return Container(
|
||||
width: ScreenUtil().setWidth(330),
|
||||
height: ScreenUtil().setWidth(110),
|
||||
alignment: const Alignment(0, 1),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey[600], width: 1),
|
||||
borderRadius: BorderRadius.circular(3),
|
||||
),
|
||||
child: FlatButton(
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: !fh_hyc
|
||||
? null
|
||||
: () {
|
||||
tsjj = !tsjj;
|
||||
//黑烟审核推送交警Checkbox改变广播
|
||||
eventBus.fire(HycsDataAuditCheckboxButton('黑烟审核推送交警Checkbox已改变', tsjj));
|
||||
print('tsjj = $tsjj');
|
||||
setState(() {});
|
||||
},
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('同时推送交警',
|
||||
style: TextStyle(color: !fh_hyc || 1 == sfyc ? Colors.grey : null, fontSize: 12)),
|
||||
SizedBox(width: 1),
|
||||
!fh_hyc || 1 == sfyc
|
||||
? Icon(Icons.check_box_outline_blank, color: Colors.grey)
|
||||
: tsjj
|
||||
? Icon(Icons.check_box, color: Colors.blue)
|
||||
: Icon(Icons.check_box_outline_blank, color: Colors.black),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return _getCheckboxButton();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'dart:async';
|
||||
|
||||
enum Action { Ok, Cancel }
|
||||
|
||||
class ConfirmDialog01 extends StatefulWidget {
|
||||
ConfirmDialog01(
|
||||
{this.title = '标题', this.msg = '提示信息', this.okText = '确定', this.cancelText = '取消'});
|
||||
|
||||
String title;
|
||||
String msg;
|
||||
String okText;
|
||||
String cancelText;
|
||||
|
||||
@override
|
||||
_ConfirmDialog01State createState() => _ConfirmDialog01State();
|
||||
}
|
||||
|
||||
class _ConfirmDialog01State extends State<ConfirmDialog01> {
|
||||
String _choice = 'Nothing';
|
||||
|
||||
Future _openAlertDialog() async {
|
||||
final action = await showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false, //// user must tap button!
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(widget.title),
|
||||
content: Text(widget.msg),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(widget.cancelText),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, Action.Cancel);
|
||||
},
|
||||
),
|
||||
FlatButton(
|
||||
child: Text(widget.okText),
|
||||
onPressed: () {
|
||||
Navigator.pop(context, Action.Ok);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
switch (action) {
|
||||
case Action.Ok:
|
||||
setState(() {
|
||||
_choice = 'Ok';
|
||||
});
|
||||
break;
|
||||
case Action.Cancel:
|
||||
setState(() {
|
||||
_choice = 'Cancel';
|
||||
});
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text('ConfirmDialog01'),
|
||||
elevation: 0.0,
|
||||
),
|
||||
body: Container(
|
||||
padding: EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text('Your choice is: $_choice'),
|
||||
SizedBox(
|
||||
height: 16.0,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
RaisedButton(
|
||||
child: Text('Open AlertDialog'),
|
||||
onPressed: _openAlertDialog,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../services/EventBus.dart';
|
||||
|
||||
class DropdownItem extends StatefulWidget {
|
||||
DropdownItem(
|
||||
{@required this.listItems,
|
||||
@required this.initValue,
|
||||
@required this.dropdownEvent,
|
||||
this.width = 180,
|
||||
this.height = 35,
|
||||
this.fontSize = 16});
|
||||
|
||||
List listItems;
|
||||
String initValue;
|
||||
double width;
|
||||
double height;
|
||||
double fontSize;
|
||||
String dropdownEvent;
|
||||
|
||||
//处理Dropdown选项改变广播
|
||||
//如果传递函数,将导致App崩溃
|
||||
//eventBus.fire(widget.dropdownEvent('Dropdown选项已改变', _selectedValue));
|
||||
//通过传字符串,用 switch 处理不会导致App崩溃
|
||||
//widget.dropdownEvent 取值:
|
||||
//case 'SelectLedDwUpdateEvent': //监听 选择LED点位 更新事件
|
||||
//case 'SelectWzjlUpdateEvent': //监听 选择显示违章记录 更新事件
|
||||
|
||||
@override
|
||||
_DropdownItemState createState() => _DropdownItemState();
|
||||
}
|
||||
|
||||
class _DropdownItemState extends State<DropdownItem> {
|
||||
List<DropdownMenuItem<String>> _dropDownMenuItems;
|
||||
String _selectedValue;
|
||||
|
||||
//try_setState(); //避免异常报错
|
||||
try_setState() {
|
||||
try {
|
||||
setState(() {});
|
||||
} catch (e) {
|
||||
print('setState(() {})异常:${e}');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_selectedValue = widget.initValue;
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
|
||||
if (widget.dropdownEvent == 'SelectWzjlUpdateEvent') {
|
||||
//eventBus.fire(SelectWzjlUpdateEvent('external_SelectWzjlUpdateEvent', getWzjlString(_mapGetLedXsxxGetData["xsts"])));
|
||||
///监听 选择显示违章记录 更新事件
|
||||
eventBus.on<SelectWzjlUpdateEvent>().listen((event) async {
|
||||
print(event.str);
|
||||
//只响应外部发送的'external_SelectWzjlUpdateEvent'
|
||||
//不响应内部发送的'insider_SelectWzjlUpdateEvent'
|
||||
if (event.str == 'external_SelectWzjlUpdateEvent') {
|
||||
//刷新页面数据
|
||||
//print('external_SelectWzjlUpdateEvent:' '_selectedValue = $_selectedValue');
|
||||
_selectedValue = event.selectedValue;
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
try_setState(); //避免异常报错
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
super.initState();
|
||||
}
|
||||
|
||||
List<DropdownMenuItem<String>> getDropDownMenuItems() {
|
||||
List<DropdownMenuItem<String>> items = [];
|
||||
int len = widget.listItems.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
items.add(
|
||||
DropdownMenuItem(
|
||||
value: widget.listItems[i],
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
(_selectedValue == widget.listItems[i])
|
||||
? Container(
|
||||
color: Colors.black12,
|
||||
child: Text(widget.listItems[i], style: TextStyle(fontSize: widget.fontSize)),
|
||||
)
|
||||
: Text(widget.listItems[i], style: TextStyle(fontSize: widget.fontSize)),
|
||||
SizedBox(width: 2),
|
||||
(_selectedValue == widget.listItems[i])
|
||||
? Icon(Icons.check, size: 18)
|
||||
: SizedBox(width: 0),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
Widget getDropdownButton() {
|
||||
//_selectedValue = initValue;
|
||||
return DropdownButtonHideUnderline(
|
||||
child: DropdownButton(
|
||||
isExpanded: true, //让下拉图标始终位于末尾
|
||||
value: _selectedValue,
|
||||
items: _dropDownMenuItems,
|
||||
onChanged: (String _selValue) {
|
||||
_selectedValue = _selValue;
|
||||
print('_selectedValue = $_selectedValue');
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
setState(() {});
|
||||
|
||||
///处理Dropdown选项改变广播
|
||||
//如果传递函数,将导致App崩溃
|
||||
//eventBus.fire(widget.dropdownEvent('Dropdown选项已改变', _selectedValue));
|
||||
//通过传字符串,用 switch 处理不会导致App崩溃
|
||||
//widget.dropdownEvent 取值:
|
||||
//case 'SelectLedDwUpdateEvent': //监听 选择LED点位 更新事件
|
||||
//case 'SelectWzjlUpdateEvent': //监听 选择显示违章记录 更新事件
|
||||
switch (widget.dropdownEvent) {
|
||||
case 'SelectDwfliterUpdateEvent': //监听 选择点位 更新事件
|
||||
eventBus.fire(SelectDwfliterUpdateEvent('Dropdown选项已改变', _selectedValue));
|
||||
break;
|
||||
case 'SelectLedDwUpdateEvent': //监听 选择LED点位 更新事件
|
||||
eventBus.fire(SelectLedDwUpdateEvent('Dropdown选项已改变', _selectedValue));
|
||||
break;
|
||||
case 'SelectWzjlUpdateEvent': //监听 选择显示违章记录 更新事件
|
||||
eventBus.fire(SelectWzjlUpdateEvent('insider_SelectWzjlUpdateEvent', _selectedValue));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment(-1, 0),
|
||||
margin: EdgeInsets.only(bottom: 0),
|
||||
padding: EdgeInsets.only(left: 5),
|
||||
height: widget.height,
|
||||
width: widget.width,
|
||||
decoration: BoxDecoration(
|
||||
//color: Colors.white,
|
||||
border: Border.all(color: Colors.grey, width: 2),
|
||||
borderRadius: BorderRadius.all(Radius.circular(3.0)),
|
||||
),
|
||||
child: getDropdownButton(),
|
||||
//child: Text('getDropdownButton'),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import '../components/hyxx_data_handle.dart';
|
||||
import '../services/EventBus.dart';
|
||||
|
||||
class DropdownItems extends StatefulWidget {
|
||||
int index;
|
||||
String initValue;
|
||||
|
||||
DropdownItems(this.index, this.initValue); //I don't know what is this index for but I will put it in anyway
|
||||
@override
|
||||
_DropdownItemsState createState() => _DropdownItemsState();
|
||||
}
|
||||
|
||||
class _DropdownItemsState extends State<DropdownItems> {
|
||||
List<DropdownMenuItem<String>> _dropDownMenuItems;
|
||||
String selectedValue;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_dropDownMenuItems = getDropDownMenuItems();
|
||||
selectedValue = widget.initValue;
|
||||
}
|
||||
|
||||
List<DropdownMenuItem<String>> getDropDownMenuItems() {
|
||||
List<DropdownMenuItem<String>> items = [];
|
||||
int len = cpysList.length;
|
||||
for (int i = 0; i < len; i++) {
|
||||
items.add(DropdownMenuItem(
|
||||
value: cpysList[i].cpysText,
|
||||
child: Text(cpysList[i].cpysText,
|
||||
style: TextStyle(
|
||||
color: cpysList[i].cpysFont,
|
||||
background: Paint()..color = cpysList[i].cpysBackground))));
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
Widget getDropdownButton() {
|
||||
//DropdownButton默认有一条下划线,DropdownButtonHideUnderline去除下划线
|
||||
return DropdownButtonHideUnderline(
|
||||
child: DropdownButton(
|
||||
value: selectedValue,
|
||||
items: _dropDownMenuItems,
|
||||
onChanged: (String _selectedFruit) {
|
||||
selectedValue = _selectedFruit;
|
||||
//黑烟初审数据审核Dropdown选项改变广播
|
||||
eventBus.fire(HycsDataAuditDropdownEvent('黑烟初审数据审核Dropdown选项已改变', selectedValue));
|
||||
setState(() {});
|
||||
print('selectedValue = $selectedValue');
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return getDropdownButton();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import 'package:flutter/material.dart';
|
||||
//
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class JdButton extends StatelessWidget {
|
||||
final Color color;
|
||||
final String text;
|
||||
final double textSize;
|
||||
final Object onTop;
|
||||
final double height;
|
||||
final double width;
|
||||
final double circular;
|
||||
|
||||
JdButton(
|
||||
{Key key,
|
||||
this.color = Colors.black,
|
||||
this.text = "按钮",
|
||||
this.textSize = 18,
|
||||
this.onTop,
|
||||
this.height = 68,
|
||||
this.width = 130,
|
||||
this.circular = 10})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: this.onTop,
|
||||
child: Container(
|
||||
alignment: Alignment(0, 0),
|
||||
margin: EdgeInsets.all(5),
|
||||
padding: EdgeInsets.all(5),
|
||||
width: ScreenUtil().setWidth(this.width),
|
||||
height: ScreenUtil().setHeight(this.height),
|
||||
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(circular)),
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(color: Colors.white, fontSize: textSize),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class JdText extends StatefulWidget {
|
||||
final String text;
|
||||
final String title;
|
||||
bool password;
|
||||
final Object onChanged;
|
||||
final int maxLines;
|
||||
final double height;
|
||||
TextEditingController controller;
|
||||
final String endBtn;
|
||||
|
||||
JdText(
|
||||
{Key key,
|
||||
this.text = "输入内容",
|
||||
this.title = '标题',
|
||||
this.password = false,
|
||||
this.onChanged,
|
||||
this.maxLines = 1,
|
||||
this.height = 68,
|
||||
this.controller,
|
||||
this.endBtn})
|
||||
: super(key: key);
|
||||
|
||||
_JdTextState createState() => _JdTextState();
|
||||
}
|
||||
|
||||
class _JdTextState extends State<JdText> {
|
||||
Icon ShowHiddenIcon = Icon(Icons.more_horiz);
|
||||
|
||||
void initState() {
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment(0, -1),
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
height: ScreenUtil().setHeight(widget.height),
|
||||
decoration:
|
||||
BoxDecoration(border: Border(bottom: BorderSide(width: 1, color: Colors.black12))),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
alignment: Alignment(0, 0),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 0, bottom: 0),
|
||||
child: Text(
|
||||
widget.title,
|
||||
style: TextStyle(
|
||||
fontSize: 17,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
//Flutter中Row中不能直接使用textfield控件
|
||||
Expanded(
|
||||
child: TextField(
|
||||
textAlignVertical: TextAlignVertical(y: 1.0),
|
||||
controller: widget.controller,
|
||||
maxLines: 1,
|
||||
obscureText: widget.password,
|
||||
decoration: InputDecoration(
|
||||
//contentPadding: EdgeInsets.only(bottom: 16),
|
||||
hintText: widget.text,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(30), borderSide: BorderSide.none),
|
||||
),
|
||||
onChanged: widget.onChanged,
|
||||
),
|
||||
),
|
||||
getBtn(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getBtn() {
|
||||
Widget btn;
|
||||
switch (widget.endBtn) {
|
||||
case 'ClearBtn':
|
||||
widget.controller = new TextEditingController();
|
||||
btn = Container(
|
||||
// alignment: Alignment(0, -1),
|
||||
// padding: EdgeInsets.only(bottom: 23),
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.highlight_off),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
widget.controller.clear();
|
||||
});
|
||||
}),
|
||||
);
|
||||
break;
|
||||
case 'ShowHiddenBtn':
|
||||
btn = Container(
|
||||
// alignment: Alignment(0, -1),
|
||||
// padding: EdgeInsets.only(bottom: 23),
|
||||
child: IconButton(
|
||||
icon: ShowHiddenIcon,
|
||||
onPressed: () {
|
||||
widget.password = !widget.password;
|
||||
setState(() {
|
||||
ShowHiddenIcon =
|
||||
widget.password ? Icon(Icons.more_horiz) : Icon(Icons.remove_red_eye);
|
||||
});
|
||||
}),
|
||||
);
|
||||
break;
|
||||
case 'OutlineButton':
|
||||
btn = Container(
|
||||
child: OutlineButton(
|
||||
borderSide: BorderSide(color: Colors.blue),
|
||||
onPressed: () {},
|
||||
child: Container(
|
||||
child: Text("获取验证码"),
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
btn = SizedBox.shrink();
|
||||
break;
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
class LoadingWidget extends StatelessWidget {
|
||||
const LoadingWidget({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
CircularProgressIndicator(
|
||||
strokeWidth: 1.0,
|
||||
),Text(
|
||||
'加载中...',
|
||||
style: TextStyle(fontSize: 16.0),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
);;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingMenu extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return IconButton(
|
||||
// action button
|
||||
icon: Icon(Icons.settings),
|
||||
onPressed: () {
|
||||
debugPrint("Click Menu Setting");
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PeakAppBar extends StatelessWidget implements PreferredSizeWidget {
|
||||
PeakAppBar({Key key, @required this.title, this.actions}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
final List<Widget> actions;
|
||||
|
||||
PeakAppBar.defaultSetting({Key key, @required this.title}) : actions = null;
|
||||
// todo settings page
|
||||
//: actions=<Widget>[SettingMenu()];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PreferredSize(
|
||||
child: AppBar(
|
||||
title: Text(this.title),
|
||||
actions: this.actions,
|
||||
),
|
||||
preferredSize: preferredSize,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Size get preferredSize => Size.fromHeight(45.0);
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:hyzp_ybqx/components/customDialogHysh.dart';
|
||||
import 'package:hyzp_ybqx/components/dioFun.dart';
|
||||
|
||||
import '../components/hyxx_data_handle.dart';
|
||||
import '../services/EventBus.dart';
|
||||
import 'CheckboxButtonItem.dart';
|
||||
|
||||
class RadioListItems extends StatefulWidget {
|
||||
RadioListItems(
|
||||
{@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
|
||||
_RadioListItemsState createState() => _RadioListItemsState();
|
||||
}
|
||||
|
||||
class _RadioListItemsState extends State<RadioListItems> {
|
||||
//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”。考虑将显式类型参数传递给泛型。
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget qxButton = getBtnSizeX(
|
||||
text: "取消",
|
||||
onPressedFun: () async {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
width: 60.0);
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
getShyj(widget.index),
|
||||
SizedBox(height: 10),
|
||||
//8、审核结果
|
||||
Divider(height: 1.0, color: Colors.blue),
|
||||
SizedBox(height: 5),
|
||||
Container(
|
||||
height: widget.size.height,
|
||||
child: 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: 140,
|
||||
groupValue: _selectedRadio,
|
||||
onChanged: (int value) {
|
||||
_selectedRadio = value;
|
||||
fh_hyc = true; //复审为黑烟车
|
||||
tsjj = true; //同时推送交警
|
||||
//黑烟初审数据审核Radio选项改变广播
|
||||
eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
|
||||
setState(() {});
|
||||
print('selectedRadio = ${_selectedRadio.toString()}');
|
||||
},
|
||||
),
|
||||
SizedBox(width: 20),
|
||||
CustomRadioWidget(
|
||||
value: 1,
|
||||
title: "非黑烟车",
|
||||
fontSize: widget.fontSize,
|
||||
width: 110,
|
||||
groupValue: _selectedRadio,
|
||||
onChanged: (int value) {
|
||||
_selectedRadio = value;
|
||||
fh_hyc = false; //复审为黑烟车
|
||||
tsjj = false; //同时推送交警
|
||||
//黑烟初审数据审核Radio选项改变广播
|
||||
eventBus.fire(HycsDataAuditRadioEvent('黑烟初审数据审核Radio选项已改变', _selectedRadio));
|
||||
setState(() {});
|
||||
print('selectedRadio = ${_selectedRadio.toString()}');
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 6),
|
||||
Divider(height: 1.0, color: Colors.blue),
|
||||
SizedBox(height: widget.hyshlx == 'hyfh' ? 3 : 30),
|
||||
//9、得到审核确认组件
|
||||
//getShqr(widget.index),
|
||||
widget.hyshlx == 'hyfh'
|
||||
? Column(
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
1 == sfyc ? _sfcyTextTrue : _sfcyTextFalse,
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(color: 1 == sfyc ? Colors.blue : null),
|
||||
)),
|
||||
SizedBox(height: 2),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: <Widget>[
|
||||
CheckboxButtonItem(widget.index),
|
||||
//_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: () 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), //'复审提交'
|
||||
qxButton, //'取消'
|
||||
],
|
||||
)
|
||||
],
|
||||
)
|
||||
: 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: () 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), //'初审提交'
|
||||
qxButton, //'取消'
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//7、得到审核意见组件
|
||||
Widget getShyj(int index) {
|
||||
return ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
minWidth: double.infinity, //宽度尽可能大
|
||||
//minHeight: _listTileHeight, //最小高度
|
||||
maxHeight: my_listTileHeight, //最大高度
|
||||
),
|
||||
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: my_listTileHeight,
|
||||
//widthTrail = 400报错,360刚能显示,300换行,260
|
||||
width: 266,
|
||||
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)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,142 @@
|
||||
import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/screen_util.dart';
|
||||
import '../components/commonFun.dart';
|
||||
|
||||
//int my_count = 0; //重试次数
|
||||
|
||||
class MyDelayToast {
|
||||
int showTime; // MyDelayToast显示时间
|
||||
double top;
|
||||
double left;
|
||||
double width;
|
||||
double height;
|
||||
|
||||
OverlayEntry _overlayEntry; // MyDelayToast靠它加到屏幕上
|
||||
Timer _timer;
|
||||
double minEdge = 2.5;
|
||||
|
||||
MyDelayToast(
|
||||
{@required BuildContext context,
|
||||
this.showTime = 5,
|
||||
this.top = 100,
|
||||
this.left = 20,
|
||||
this.width = 80,
|
||||
this.height = 50}) {
|
||||
OverlayState overlayState = Overlay.of(context);
|
||||
startTimer();
|
||||
if (_overlayEntry == null) {
|
||||
_overlayEntry = OverlayEntry(
|
||||
builder: (BuildContext context) {
|
||||
return Positioned(
|
||||
top: top,
|
||||
left: left,
|
||||
child: Draggable(
|
||||
child: getView(context),
|
||||
feedback: getView(context),
|
||||
onDragStarted: () {
|
||||
print('onDragStarted:');
|
||||
},
|
||||
// onDragEnd: (detail) {
|
||||
// print('onDragEnd:${detail.offset}');
|
||||
// getView(top: detail.offset.dy, left: detail.offset.dx);
|
||||
// },
|
||||
onDraggableCanceled: (Velocity velocity, Offset _offset) {
|
||||
//ScreenUtil().statusBarHeight //Top Status bar height , Notch will be higher
|
||||
//ScreenUtil().bottomBarHeight //Bottom safe zone distance, suitable for buttons with full screen
|
||||
top = _offset.dy <= ScreenUtil().statusBarHeight
|
||||
? ScreenUtil().statusBarHeight + minEdge
|
||||
: (_offset.dy <
|
||||
ScreenUtil().screenHeight - height - ScreenUtil().bottomBarHeight)
|
||||
? _offset.dy
|
||||
: (ScreenUtil().screenHeight -
|
||||
height -
|
||||
ScreenUtil().bottomBarHeight -
|
||||
minEdge);
|
||||
left = _offset.dx < minEdge
|
||||
? minEdge
|
||||
: (_offset.dx < ScreenUtil().screenWidth - width - minEdge)
|
||||
? _offset.dx
|
||||
: (ScreenUtil().screenWidth - width - minEdge);
|
||||
getView(context);
|
||||
_overlayEntry.markNeedsBuild();
|
||||
},
|
||||
childWhenDragging: Container(),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
overlayState.insert(_overlayEntry);
|
||||
} else {
|
||||
//重新绘制UI,类似setState
|
||||
_overlayEntry.markNeedsBuild();
|
||||
}
|
||||
}
|
||||
|
||||
Widget getView(BuildContext context, {double width = 80, double height = 50}) {
|
||||
return GestureDetector(
|
||||
child: Container(
|
||||
width: width,
|
||||
height: height,
|
||||
padding: EdgeInsets.all(0),
|
||||
color: Theme.of(context).buttonColor,
|
||||
child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
|
||||
Text('第 ${getCount} 次获取 ',
|
||||
style: TextStyle(
|
||||
fontFamily: Theme.of(context).accentTextTheme.caption.fontFamily,
|
||||
fontSize: 13,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
textAlign: TextAlign.center),
|
||||
Text('(${showTime} 秒)',
|
||||
style: TextStyle(
|
||||
fontFamily: Theme.of(context).accentTextTheme.caption.fontFamily,
|
||||
fontSize: 13,
|
||||
color: Colors.black,
|
||||
decoration: TextDecoration.none,
|
||||
fontWeight: FontWeight.normal,
|
||||
),
|
||||
textAlign: TextAlign.center),
|
||||
]),
|
||||
),
|
||||
onTap: () {},
|
||||
onDoubleTap: () {
|
||||
endMyDelayToast();
|
||||
},
|
||||
onLongPress: () {
|
||||
endMyDelayToast();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
endMyDelayToast() async {
|
||||
_timer?.cancel();
|
||||
_overlayEntry.markNeedsBuild();
|
||||
await Future.delayed(Duration(milliseconds: 400));
|
||||
_overlayEntry.remove();
|
||||
_overlayEntry = null;
|
||||
}
|
||||
|
||||
void startTimer() {
|
||||
_timer = Timer.periodic(
|
||||
Duration(seconds: 1),
|
||||
(Timer timer) {
|
||||
if (showTime < 1) {
|
||||
timer.cancel();
|
||||
endMyDelayToast();
|
||||
} else {
|
||||
if (!getingDwVideo) {
|
||||
endMyDelayToast();
|
||||
}
|
||||
showTime--;
|
||||
// if (showTime % 3 == 0) {
|
||||
// getCount++;
|
||||
// }
|
||||
_overlayEntry.markNeedsBuild();
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,620 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_screenutil/screen_util.dart';
|
||||
import 'package:flutter_superplayer/flutter_superplayer.dart';
|
||||
import 'package:flutterptcontrol/flutterptcontrol.dart';
|
||||
import 'package:hyzp_ybqx/components/commonFun.dart';
|
||||
import 'package:hyzp_ybqx/components/dioFun.dart';
|
||||
import 'package:hyzp_ybqx/provider/player_ratio.dart';
|
||||
import 'package:hyzp_ybqx/provider/player_region.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../components/commonFun.dart';
|
||||
import '../services/Storage.dart';
|
||||
|
||||
const _kControlViewTypes = [kControlViewTypeDefault, kControlViewTypeWithout];
|
||||
|
||||
class SuperPlayerPage extends StatefulWidget {
|
||||
SuperPlayerPage(
|
||||
{@required this.url,
|
||||
this.id = -2, // 播放点位视频的点位编号,-2 表示播放违章视频
|
||||
this.loop = 1,
|
||||
this.title = 'Tencent Player',
|
||||
Key key})
|
||||
: super(key: key);
|
||||
String url;
|
||||
String title;
|
||||
int loop; //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
|
||||
int id;
|
||||
|
||||
@override
|
||||
_SuperPlayerPageState createState() => _SuperPlayerPageState();
|
||||
}
|
||||
|
||||
class _SuperPlayerPageState extends State<SuperPlayerPage> with SuperPlayerListener {
|
||||
SuperPlayerController _playerController = SuperPlayerController();
|
||||
|
||||
String _sdkVersion = 'Unknown';
|
||||
List<String> _logs = [];
|
||||
bool bFullScreen = false;
|
||||
|
||||
String _controlViewType = _kControlViewTypes.first;
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
Playing = false;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
//initPlatformState();
|
||||
// Future.delayed(const Duration(milliseconds: 1000), () {
|
||||
// _playerController.playWithModel(SuperPlayerModel(url: widget.url));
|
||||
// setState(() {
|
||||
// });
|
||||
// });
|
||||
init();
|
||||
}
|
||||
|
||||
Future<void> init() async {
|
||||
await _playerController.addListener(this);
|
||||
await initPlatformState();
|
||||
if (!mounted) return;
|
||||
print('mounted = ${mounted}');
|
||||
// 开启调试日志
|
||||
//await FTXPlayerController.setConsoleEnabled(true);
|
||||
// 初始化播放器
|
||||
//await _controller.initialize(onlyAudio: true);
|
||||
|
||||
await _playerController.uiHideDanmu(); // 隐藏弹幕
|
||||
//设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
|
||||
if (0 == widget.loop) {
|
||||
await _playerController.setLoop(true);
|
||||
}
|
||||
|
||||
await _playerController.playWithModel(testSuperPlayerModel);
|
||||
//_controller.play("http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4");
|
||||
// _controller
|
||||
// .play('rtmp://125.64.218.67:9901/rtp/gb_play_34020000001320003016_34020000001320003016');
|
||||
// 设置循环播放
|
||||
//await _controller.setLoop(true);
|
||||
// 开始播放
|
||||
//await _controller.play("http://125.64.218.67:9908/video/2_6063_20210409_140608_川Q31715.mp4");
|
||||
}
|
||||
|
||||
SuperPlayerModel get testSuperPlayerModel {
|
||||
// int appId = 1252463788;
|
||||
// String fileId = "5285890781763144364";
|
||||
|
||||
SuperPlayerModel superPlayerModel = SuperPlayerModel(
|
||||
url: widget.url,
|
||||
// appId: appId,
|
||||
// videoId: SuperPlayerVideoId(fileId: fileId),
|
||||
);
|
||||
return superPlayerModel;
|
||||
}
|
||||
|
||||
// Platform messages are asynchronous, so we initialize in an async method.
|
||||
Future<void> initPlatformState() async {
|
||||
String sdkVersion;
|
||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||
try {
|
||||
sdkVersion = await FlutterSuperPlayer.sdkVersion;
|
||||
} on PlatformException {
|
||||
sdkVersion = 'Failed to get platform version.';
|
||||
}
|
||||
print('sdkVersion = ${sdkVersion}');
|
||||
print('mounted = ${mounted}');
|
||||
|
||||
// If the widget was removed from the tree while the asynchronous platform
|
||||
// message was in flight, we want to discard the reply rather than calling
|
||||
// setState to update our non-existent appearance.
|
||||
if (!mounted) return;
|
||||
|
||||
setState(() {
|
||||
_sdkVersion = sdkVersion;
|
||||
});
|
||||
}
|
||||
|
||||
void _addLog(String method, dynamic data) {
|
||||
_logs.add('>>>$method');
|
||||
if (data != null) {
|
||||
_logs.add(data is Map ? json.encode(data) : data);
|
||||
}
|
||||
_logs.add(' ');
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
PlayerRatioProvide playerRatioProvide;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
playerRegionProvide = Provider.of<PlayerRegionProvide>(context);
|
||||
playerRatioProvide = Provider.of<PlayerRatioProvide>(context);
|
||||
List<Widget> listData = getDataListControl2();
|
||||
double btnHeight1 = 70; //第一按钮行高度
|
||||
double btnHeight2 = 160; //第二按钮行高度
|
||||
int btnCount = 4; //每行按钮个数
|
||||
int btnCount3 = listData.length; //每行按钮个数
|
||||
var mediaSize = MediaQuery.of(context).size;
|
||||
//远程控制球机方向按钮外半径和内半径
|
||||
double _outerRadius = 270;
|
||||
double _innerRadius = _outerRadius / 2;
|
||||
|
||||
//double barHeight = bFullScreen ? 0 : MediaQueryData.fromWindow(window).padding.top;
|
||||
return Scaffold(
|
||||
appBar: bFullScreen
|
||||
? null
|
||||
: 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(widget.title,
|
||||
style: TextStyle(color: Colors.white, fontSize: 18),
|
||||
textAlign: TextAlign.center,
|
||||
overflow: TextOverflow.ellipsis),
|
||||
),
|
||||
SizedBox(width: 50),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
body: WillPopScope(
|
||||
child: Container(
|
||||
// height: ScreenUtil().screenHeight -
|
||||
// ScreenUtil().statusBarHeight -
|
||||
// ScreenUtil().bottomBarHeight,
|
||||
color: Color.fromRGBO(224, 224, 224, 1),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
//第2行组件,视频播放区
|
||||
Center(
|
||||
child: Container(
|
||||
//padding: EdgeInsets.only(top: barHeight),
|
||||
alignment: Alignment(0, -1),
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: MediaQuery.of(context).size.width * (9 / 16),
|
||||
color: Colors.black,
|
||||
child: Stack(
|
||||
children: [
|
||||
_playState <= 2 ? getMoreWidget(strokeWidth: 3.0) : SizedBox.shrink(),
|
||||
SuperPlayerView(
|
||||
controller: _playerController,
|
||||
controlViewType: _kControlViewTypes[0],
|
||||
),
|
||||
//_playState < 3 ? SizedBox.shrink() : getMoreWidget(strokeWidth: 3.0),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
//第3.1行组件,控制按钮区
|
||||
bFullScreen ? SizedBox.shrink() : SizedBox(height: ScreenUtil().setHeight(69)),
|
||||
bFullScreen
|
||||
? SizedBox.shrink()
|
||||
: Row(
|
||||
children: [
|
||||
SizedBox(width: ScreenUtil().setWidth(347)),
|
||||
getRoundButton(
|
||||
//(bPlaying) ? '暂停' : '播放',
|
||||
text: playerRegionProvide.playerText,
|
||||
icon: playerRegionProvide.playerIcon,
|
||||
diameter: 130,
|
||||
onPress: playOrPause,
|
||||
),
|
||||
SizedBox(width: ScreenUtil().setWidth(104)),
|
||||
getRoundButton(
|
||||
text: '刷新',
|
||||
icon: Icons.autorenew,
|
||||
diameter: 130,
|
||||
onPress: () {
|
||||
restartPlay(urlnew);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
bFullScreen ? SizedBox.shrink() : SizedBox(height: ScreenUtil().setHeight(79)),
|
||||
bFullScreen
|
||||
? SizedBox.shrink()
|
||||
: Container(
|
||||
height: ScreenUtil().setHeight(2 * _outerRadius),
|
||||
width: ScreenUtil().setWidth(2 * _outerRadius),
|
||||
child: PtControlWidget(
|
||||
// innerRadius: _innerRadius,
|
||||
// outerRadius: _outerRadius,
|
||||
// 进行像素单位转换,解决按钮响应错乱问题
|
||||
innerRadius: _innerRadius / ScreenUtil().pixelRatio,
|
||||
outerRadius: _outerRadius / ScreenUtil().pixelRatio,
|
||||
callback: -2 == widget.id
|
||||
? null
|
||||
: (status) {
|
||||
///点击回调
|
||||
print('status = $status');
|
||||
switch (status) {
|
||||
|
||||
/// status == -1 超出范围
|
||||
/// status == 0 右
|
||||
case 0:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 1);
|
||||
break;
|
||||
|
||||
/// status == 1 右上
|
||||
case 1:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 9);
|
||||
break;
|
||||
|
||||
///三、球机位移接口方向代码说明:
|
||||
// 上:8 下:4 左:2 右:1 左上:10 左下:6 右上:9 右下:5
|
||||
/// status == 2 上
|
||||
case 2:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 8);
|
||||
break;
|
||||
|
||||
/// status == 3 左上
|
||||
case 3:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 10);
|
||||
break;
|
||||
|
||||
/// status == 4 左
|
||||
case 4:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 2);
|
||||
break;
|
||||
|
||||
/// status == 5 左下
|
||||
case 5:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 6);
|
||||
break;
|
||||
|
||||
/// status == 6 下
|
||||
case 6:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 4);
|
||||
break;
|
||||
|
||||
/// status == 7 右下
|
||||
case 7:
|
||||
setSphericalCameraDio(id: widget.id, cmdCode: 5);
|
||||
break;
|
||||
|
||||
/// status == 8 还原
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
),
|
||||
// child: GridView.custom(
|
||||
// // padding: EdgeInsets.only(
|
||||
// // left: ScreenUtil().setWidth(35), right: ScreenUtil().setWidth(35)),
|
||||
// gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
// crossAxisCount: btnCount3,
|
||||
// mainAxisSpacing: 0,
|
||||
// crossAxisSpacing: 1,
|
||||
// childAspectRatio: ratio3,
|
||||
// ),
|
||||
// childrenDelegate: SliverChildBuilderDelegate((context, position) {
|
||||
// return getItemContainer(listData[position]);
|
||||
// }, childCount: btnCount3)),
|
||||
),
|
||||
//SizedBox(height: ScreenUtil().setHeight(49)),
|
||||
//Divider(color: Colors.blue),
|
||||
//第4行组件,分隔栏
|
||||
// Container(
|
||||
// //height: 11,
|
||||
// height: ScreenUtil().setHeight(28),
|
||||
// color: Color.fromRGBO(224, 224, 224, 1),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
onWillPop: () {
|
||||
Playing = false;
|
||||
getingDwVideo = false;
|
||||
Navigator.pop(context); //关闭弹框,播放输入视频地址
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void onClickFloatCloseBtn() {
|
||||
_addLog('onClickFloatCloseBtn', {});
|
||||
}
|
||||
|
||||
@override
|
||||
void onClickSmallReturnBtn() {
|
||||
_addLog('onClickSmallReturnBtn', {});
|
||||
Navigator.maybePop(context);
|
||||
}
|
||||
|
||||
@override
|
||||
void onFullScreenChange(bool isFullScreen) {
|
||||
_addLog('onFullScreenChange', {'isFullScreen': isFullScreen});
|
||||
bFullScreen = !bFullScreen;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void onPlayProgressChange(int current, int duration) {
|
||||
_addLog('onPlayProgressChange', {'current': current, 'duration': duration});
|
||||
}
|
||||
|
||||
int _playState = 4;
|
||||
int i = 0;
|
||||
|
||||
@override
|
||||
void onPlayStateChange(int playState) {
|
||||
_playState = playState;
|
||||
i++;
|
||||
print('$i、playState = $playState');
|
||||
_addLog('onPlayStateChange', {'playState': playState});
|
||||
setPlayOrPauseIcon(playState);
|
||||
}
|
||||
|
||||
void setPlayOrPauseIcon(int state) {
|
||||
//state : 1 播放状态,2 暂停状态
|
||||
print('state = $state');
|
||||
if (1 == state) {
|
||||
bPlaying = true;
|
||||
} else {
|
||||
bPlaying = false;
|
||||
}
|
||||
playerRegionProvide.changePlayerState(bPlaying);
|
||||
Storage.setString('bPlaying', bPlaying ? 'true' : 'false');
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
void onStartFloatWindowPlay() {
|
||||
_addLog('onStartFloatWindowPlay', {});
|
||||
}
|
||||
|
||||
//生成圆形按钮部件
|
||||
Widget getRoundButton(
|
||||
{double diameter = 144,
|
||||
double marginVer = 10,
|
||||
String text,
|
||||
IconData icon,
|
||||
double fontSize = 16,
|
||||
double iconSize = 90,
|
||||
Color color = const Color.fromRGBO(52, 157, 237, 1),
|
||||
var onPress}) {
|
||||
return InkWell(
|
||||
onTap: onPress,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: ScreenUtil().setWidth(diameter),
|
||||
height: ScreenUtil().setHeight(diameter),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
icon,
|
||||
size: ScreenUtil().setWidth(iconSize),
|
||||
color: Color.fromRGBO(52, 157, 237, 1),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(200)),
|
||||
border: Border.all(width: 0, style: BorderStyle.none),
|
||||
),
|
||||
),
|
||||
SizedBox(height: ScreenUtil().setHeight(marginVer)),
|
||||
Text(text, style: TextStyle(fontSize: fontSize, color: Color.fromRGBO(139, 139, 139, 1))),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool bPlaying = true;
|
||||
|
||||
void playOrPause() {
|
||||
//state : 1 播放状态,2 暂停状态
|
||||
_playerController.getPlayState().then((state) {
|
||||
print('state = $state');
|
||||
if (1 == state) {
|
||||
bPlaying = false;
|
||||
_playerController.pause();
|
||||
} else {
|
||||
bPlaying = true;
|
||||
_playerController.resume();
|
||||
}
|
||||
playerRegionProvide.changePlayerState(bPlaying);
|
||||
Storage.setString('bPlaying', bPlaying ? 'true' : 'false');
|
||||
setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
void restartPlay(String url) async {
|
||||
_playState = 4;
|
||||
bPlaying = true;
|
||||
_playerController.resetPlayer();
|
||||
_playerController.resume();
|
||||
// //writeCurrentPosFile();
|
||||
// await player.stop();
|
||||
// await player.reset();
|
||||
// await player.setOption(FijkOption.playerCategory, "mediacodec-all-videos", 1);
|
||||
// await player.setOption(FijkOption.hostCategory, "enable-snapshot", 1);
|
||||
// await player.setOption(FijkOption.hostCategory, "request-screen-on", 1);
|
||||
// await player.setOption(FijkOption.hostCategory, "request-audio-focus", 1);
|
||||
// await player.setOption(FijkOption.hostCategory, "enable-accurate-seek", 1);
|
||||
// await player.setOption(FijkOption.hostCategory, "max-buffer-size", 500 * 1024);
|
||||
// await player.setDataSource(url, autoPlay: true).catchError((e) {
|
||||
// print("setDataSource error: $e");
|
||||
// });
|
||||
// await player.setLoop(widget.loop); //设置播放循环,默认播放器的循环次数是1, 即不循环播放。如果设置循环次数0,表示无限循环。
|
||||
// bPlaying = true;
|
||||
// setState(() {});
|
||||
// playerRegionProvide.changePlayerState(bPlaying);
|
||||
}
|
||||
|
||||
//生成播放控制区第2行按钮List
|
||||
List<Widget> getDataListControl2() {
|
||||
double _diameter = 100;
|
||||
double _iconSize = 70;
|
||||
double _fontSize = 14;
|
||||
double _marginVer = 8;
|
||||
|
||||
List<Widget> list = [
|
||||
// getRoundButton(
|
||||
// diameter: _diameter,
|
||||
// iconSize: _iconSize,
|
||||
// text: '快退',
|
||||
// icon: Icons.fast_rewind,
|
||||
// onPress: () {
|
||||
// fastSeek(false);
|
||||
// },
|
||||
// ),
|
||||
// getRoundButton(
|
||||
// diameter: _diameter,
|
||||
// iconSize: _iconSize,
|
||||
// text: '快进',
|
||||
// icon: Icons.fast_forward,
|
||||
// onPress: () {
|
||||
// fastSeek(true);
|
||||
// },
|
||||
// ),
|
||||
getRoundButton(
|
||||
diameter: _diameter,
|
||||
iconSize: _iconSize,
|
||||
fontSize: _fontSize,
|
||||
marginVer: _marginVer,
|
||||
text: '放大',
|
||||
icon: Icons.zoom_in,
|
||||
onPress: () {
|
||||
//print('Icons.videocam');
|
||||
//_inputDialog(context2);
|
||||
if (10 >= playerRatioProvide.scale) {
|
||||
playerRatioProvide.changeScale(playerRatioProvide.scale + 0.5);
|
||||
}
|
||||
},
|
||||
),
|
||||
getRoundButton(
|
||||
diameter: _diameter,
|
||||
iconSize: _iconSize,
|
||||
fontSize: _fontSize,
|
||||
marginVer: _marginVer,
|
||||
text: '缩小',
|
||||
icon: Icons.zoom_out,
|
||||
onPress: () {
|
||||
//print('Icons.videocam');
|
||||
//_getFileDialog(context2);
|
||||
if (1 < playerRatioProvide.scale) {
|
||||
playerRatioProvide.changeScale(playerRatioProvide.scale - 0.5);
|
||||
}
|
||||
},
|
||||
),
|
||||
// _getIconAndTextButton(
|
||||
// '还原',
|
||||
// Icons.reply,
|
||||
// Colors.orange,
|
||||
// () {
|
||||
// //print('Icons.videocam');
|
||||
// //_getFileDialog(context2);
|
||||
// // 更新当前位置
|
||||
// playerRatioProvide.changeScale(1.0);
|
||||
// playerRatioProvide.changeOffset(Offset(0, 0));
|
||||
// playerRatioProvide.changeDeltaX(0.0);
|
||||
// playerRatioProvide.changeDeltaY(0.0);
|
||||
// },
|
||||
// ),
|
||||
getRoundButton(
|
||||
diameter: _diameter,
|
||||
iconSize: _iconSize,
|
||||
fontSize: _fontSize,
|
||||
marginVer: _marginVer,
|
||||
text: '截图',
|
||||
icon: Icons.camera_alt,
|
||||
onPress: () {
|
||||
//通过上面定义的key,才能准确调用该类型的该对象的方法
|
||||
//_myFijkPanelWidgetBuilderStateKey.currentState.takeSnapshot();
|
||||
//_fijkPanelWidgetBuilder.currentState..takeSnapshot();
|
||||
takeSnapshot();
|
||||
},
|
||||
),
|
||||
getRoundButton(
|
||||
diameter: _diameter,
|
||||
iconSize: _iconSize,
|
||||
fontSize: _fontSize,
|
||||
marginVer: _marginVer,
|
||||
text: '全屏',
|
||||
icon: Icons.fullscreen,
|
||||
onPress: () {
|
||||
//player.enterFullScreen();
|
||||
_playerController.toFullScreen();
|
||||
},
|
||||
),
|
||||
];
|
||||
return list;
|
||||
}
|
||||
|
||||
void takeSnapshot() {
|
||||
// player.takeSnapShot().then((v) {
|
||||
// var provider = MemoryImage(v);
|
||||
// precacheImage(provider, context).then((_) {
|
||||
// setState(() {
|
||||
// myImageProvider = provider;
|
||||
// });
|
||||
// });
|
||||
// FijkLog.d("get snapshot succeed");
|
||||
//
|
||||
// //Uint8List fileData;
|
||||
// String fileFath;
|
||||
// ImageSaver.save('extended_image_cropped_image.jpg', v).then((value) {
|
||||
// fileFath = value;
|
||||
// // var fileFath = await ImagePickerSaver.saveFile(fileData: fileData);
|
||||
// print('my save fileFath : $fileFath');
|
||||
// });
|
||||
// }).catchError((e) {
|
||||
// FijkLog.d("get snapshot failed");
|
||||
// });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
||||
import 'table_cell.dart';
|
||||
|
||||
class TableBody extends StatefulWidget {
|
||||
// 所有点位 31 天的车流量日统计数据,每天有 3 个数据:车流量、早高峰、晚高峰
|
||||
Map mapTableData; // 有 31 个元素,每个元素又是一个 Map:包含车流量、早高峰、晚高峰
|
||||
final ScrollController scrollController;
|
||||
|
||||
TableBody({
|
||||
@required this.scrollController,
|
||||
@required this.mapTableData,
|
||||
});
|
||||
|
||||
@override
|
||||
_TableBodyState createState() => _TableBodyState();
|
||||
}
|
||||
|
||||
class _TableBodyState extends State<TableBody> {
|
||||
LinkedScrollControllerGroup _controllers;
|
||||
ScrollController _firstColumnController;
|
||||
ScrollController _restColumnsController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controllers = LinkedScrollControllerGroup();
|
||||
_firstColumnController = _controllers.addAndGet();
|
||||
_restColumnsController = _controllers.addAndGet();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_firstColumnController.dispose();
|
||||
_restColumnsController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
List listWidth = [
|
||||
100.0,
|
||||
80.0,
|
||||
80.0,
|
||||
80.0,
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
controller: _restColumnsController,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
children: List.generate(widget.mapTableData.length, (index1) {
|
||||
// 降序生成
|
||||
int rIndex1 = widget.mapTableData.length - 1 - index1;
|
||||
String key1 = widget.mapTableData.keys.elementAt(rIndex1);
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(4, (index2) {
|
||||
String key2 = '';
|
||||
if (index2 > 0) {
|
||||
key2 = widget.mapTableData[key1].keys.elementAt(index2 - 1);
|
||||
}
|
||||
|
||||
return MultiplicationTableCell(
|
||||
width: listWidth[index2],
|
||||
height: cellHeight,
|
||||
fontsize: 0 == index2 ? 14 : 16,
|
||||
edgeRight: ' ',
|
||||
text: 0 == index2
|
||||
? '${rIndex1 + 1}.${key1}'
|
||||
: widget.mapTableData[key1][key2].toString(),
|
||||
//text: _text,
|
||||
);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
// children: List.generate(31, (y) {
|
||||
// return Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: List.generate(4, (x) {
|
||||
// return MultiplicationTableCell(
|
||||
// value: (x + 2) * (y + 2),
|
||||
// width: listWidth[x],
|
||||
// height: cellHeight,
|
||||
// text: 0 == x ? '${y + 1}.${(x + 2) * (y + 2)}' : '',
|
||||
// );
|
||||
// }),
|
||||
// );
|
||||
// }),
|
||||
);
|
||||
|
||||
//Row(
|
||||
//children:
|
||||
//[
|
||||
// SizedBox(
|
||||
// width: cellWidth,
|
||||
// child: ListView(
|
||||
// controller: _firstColumnController,
|
||||
// physics: ClampingScrollPhysics(),
|
||||
// children: List.generate(maxNumber - 1, (index) {
|
||||
// return MultiplicationTableCell(
|
||||
// //color: Colors.yellow.withOpacity(0.3),
|
||||
// value: index + 2,
|
||||
// );
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
// Expanded(
|
||||
// child: SingleChildScrollView(
|
||||
// controller: widget.scrollController,
|
||||
// scrollDirection: Axis.horizontal,
|
||||
// physics: const ClampingScrollPhysics(),
|
||||
// child: SizedBox(
|
||||
// width: (maxNumber - 1) * cellWidth,
|
||||
// child: ListView(
|
||||
// controller: _restColumnsController,
|
||||
// physics: const ClampingScrollPhysics(),
|
||||
// children: List.generate(maxNumber - 1, (y) {
|
||||
// return Row(
|
||||
// children: List.generate(maxNumber - 1, (x) {
|
||||
// return MultiplicationTableCell(
|
||||
// value: (x + 2) * (y + 2),
|
||||
// );
|
||||
// }),
|
||||
// );
|
||||
// }),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
//],
|
||||
//);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
const double cellWidth = 50;
|
||||
const double cellHeight = 25;
|
||||
const double headHeight = 30;
|
||||
|
||||
class MultiplicationTableCell extends StatelessWidget {
|
||||
final String text;
|
||||
final Color color;
|
||||
double width;
|
||||
double height;
|
||||
double fontsize;
|
||||
AlignmentGeometry alignment;
|
||||
String edgeRight;
|
||||
|
||||
MultiplicationTableCell({
|
||||
this.text = '',
|
||||
this.color,
|
||||
this.width = cellWidth,
|
||||
this.height = cellWidth,
|
||||
this.fontsize = 16,
|
||||
this.alignment = Alignment.centerRight,
|
||||
this.edgeRight = ' ',
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: height,
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
border: Border.all(
|
||||
color: Colors.black12,
|
||||
width: 1.0,
|
||||
),
|
||||
),
|
||||
alignment: alignment,
|
||||
child: Text(text + edgeRight, style: TextStyle(fontSize: fontsize)),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'table_cell.dart';
|
||||
|
||||
class TableHead extends StatelessWidget {
|
||||
final ScrollController scrollController;
|
||||
|
||||
TableHead({
|
||||
@required this.scrollController,
|
||||
});
|
||||
|
||||
Widget getHeadText(String text, {double height = 30}) {
|
||||
return Container(
|
||||
alignment: Alignment.center,
|
||||
height: height,
|
||||
child: Text(text, style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
);
|
||||
}
|
||||
|
||||
List listHead = [
|
||||
'统计时间',
|
||||
'车流量',
|
||||
'早高峰',
|
||||
'晚高峰',
|
||||
];
|
||||
|
||||
List listWidth = [
|
||||
100.0,
|
||||
80.0,
|
||||
80.0,
|
||||
80.0,
|
||||
];
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
alignment: Alignment(0, 0),
|
||||
height: headHeight,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(listHead.length, (index) {
|
||||
return MultiplicationTableCell(
|
||||
color: Colors.yellow.withOpacity(0.3),
|
||||
text: listHead[index],
|
||||
width: listWidth[index],
|
||||
);
|
||||
}),
|
||||
|
||||
// children: [
|
||||
// // getHeadText('统计时间'),
|
||||
// // getHeadText('车流量'),
|
||||
// // getHeadText('早高峰'),
|
||||
// // getHeadText('晚高峰'),
|
||||
// // MultiplicationTableCell(
|
||||
// // color: Colors.yellow.withOpacity(0.3),
|
||||
// // value: 1,
|
||||
// // ),
|
||||
// // Expanded(
|
||||
// // child: ListView(
|
||||
// // //controller: scrollController, //注释掉该行,便只能上下滚动
|
||||
// // physics: ClampingScrollPhysics(),
|
||||
// // scrollDirection: Axis.horizontal,
|
||||
// // children: List.generate(maxNumber - 1, (index) {
|
||||
// // return MultiplicationTableCell(
|
||||
// // color: Colors.yellow.withOpacity(0.3),
|
||||
// // value: index + 2,
|
||||
// // );
|
||||
// // }),
|
||||
// // ),
|
||||
// // ),
|
||||
// ],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:linked_scroll_controller/linked_scroll_controller.dart';
|
||||
|
||||
import 'table_head.dart';
|
||||
import 'table_body.dart';
|
||||
|
||||
class TableScrollable extends StatefulWidget {
|
||||
// 所有点位 31 天的车流量日统计数据,每天有 3 个数据:车流量、早高峰、晚高峰
|
||||
Map mapTableData; // 有 31 个元素,每个元素又是一个 Map:包含车流量、早高峰、晚高峰
|
||||
|
||||
TableScrollable({
|
||||
@required this.mapTableData,
|
||||
});
|
||||
|
||||
@override
|
||||
_TableScrollableState createState() => _TableScrollableState();
|
||||
}
|
||||
|
||||
class _TableScrollableState extends State<TableScrollable> {
|
||||
LinkedScrollControllerGroup _controllers;
|
||||
ScrollController _headController;
|
||||
ScrollController _bodyController;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controllers = LinkedScrollControllerGroup();
|
||||
_headController = _controllers.addAndGet();
|
||||
_bodyController = _controllers.addAndGet();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_headController.dispose();
|
||||
_bodyController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
TableHead(
|
||||
scrollController: _headController,
|
||||
),
|
||||
Expanded(
|
||||
child: TableBody(
|
||||
scrollController: _bodyController,
|
||||
mapTableData: widget.mapTableData,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user