import 'dart:convert'; import 'dart:developer' as developer; import 'dart:io'; import 'dart:math'; import 'package:ai_save_account/ai_save_account.dart'; import 'package:camera/camera.dart'; import 'package:convert/convert.dart'; import 'package:crypto/crypto.dart' as crypto; import 'package:device_info/device_info.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; //import '../my_wechat_assets_picker_fix/my_asset_picker_1.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:hyzp_ybqx/provider/player_region.dart'; import 'UserInfo.dart'; //////////////////////////////////////////// // begin hyzp_ybqx-Commit022-区县切换新方法-OK // 1、修改手机桌面的App图标文本 // R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\AndroidManifest.xml // android:label="宜宾黑烟抓拍" // android:label="宜宾市翠屏黑烟抓拍" // android:label="宜宾三江新区黑烟抓拍" // android:label="宜宾市长宁黑烟抓拍" // android:label="宜宾市筠连黑烟抓拍" // android:label="宜宾市兴文黑烟抓拍" // 2、修改App的android和Flutter启动图片,制作并运行 hyzp_ybqx.images_copy.cmd,自动完成两项拷贝任务 // (1)、拷贝不同分辨率的图片文件hyzp_ybqx_launche.png到下面目录,作为App的android启动图片 // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-hdpi\ // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-mdpi\ // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xhdpi\ // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xxhdpi\ // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\android\app\src\main\res\mipmap-xxxhdpi\ // (2)、拷贝 750 * 1334 的图片文件到下面目录,作为App的Flutter启动图片 // r:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\assets\images\hyzp_ybqx01_cuiping_launche.png // 3、修改文本变量 // 位于文件 R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\lib\components\commonFun.dart 中 // 511501、宜宾市 // String APPkey = 'ijddvzgEGaxbzsbmCtpdohxHyrAArwJB'; // 宜宾市APPkey // String service_tel = '\n服务热线:187-8467-8300'; // String yibin_QuXian = '宜宾'; // String copyright_info = '© ' + yibin_QuXian + '市生态环境局 四川省踏石科技有限公司 版权所有' + service_tel; // String copyright_info_PinYin = 'YIBIN BLACK SMOKE CAR CAPTURE SYSTEM'; // const serviceUrl_ybqx = 'http://125.64.218.67:9904'; // 宜宾市 // const serviceUrl_ybqx_media = 'http://125.64.218.67:9908/'; // 宜宾市 // 区县APPkey String APPkey = 'pdohxHyr79ddvzgE8ArwGaxb01bmCtJB'; // 区县后台地址 const serviceUrl_ybqx = 'http://125.64.218.67:9909'; // 区县违章图片和视频地址前缀 // const serviceUrl_ybqx_media = 'http://125.64.218.67:9912/'; // 20220320,罗腾-子非鱼: @闵军 区县端口视频文件和图片文件的前缀,由原来的 http://125.64.218.67:9912/ 调整为 http://125.64.218.67:9906/ // 罗腾-子非鱼: 9912端口已被禁用 const serviceUrl_ybqx_media = 'http://125.64.218.67:9906/'; // 区县球机方向控制地址 // const String setSphericalCameraUrl = 'http://125.64.218.67:9914/'; //原来的 // 罗腾-子非鱼:因环保局缩减了我们的端口数量,现在对控制球机的接口进行调整。 // 1、控制端口由原来的 9914 调整为 9903; // 2、新增sip参数,0表示市级平台,1表示区县平台。之前是通过不同端口来分别访问市级和区县的,因缩减了我们的端口数,现在统一使用1个端口,通过sip参数来区分市级和区县 const String setSphericalCameraUrl = 'http://125.64.218.67:9903/'; //新版的 const int g_sip = 1; // 新增sip参数,0表示市级平台,1表示区县平台。 // { // "ret": 200, // "data": { // "is_login": true, // "user_id": 152, // "token": "959091E2A5E362E22F22F8DBE05737A95545A43AF28B19AB3DAD5F8557EE2E29", // "qx_code": "511528", // "qx_name": "兴文县" // }, // "msg": "" // } // 一套APP适应多个区县,等用户登录后,会返回 qx_code、qx_name int qx_code = -1; String qx_name = ''; String qx_name_long = ''; int qx_trial_tag = 0; String service_tel = ''; String copyright_info = ''; String copyright_info_PinYin = ''; // 区县中心地址 double center_latitude = -1; // 区县中心纬度 double center_longitude = -1; // 区县中心经度 clear_user_info() { qx_code = -1; qx_name = ''; qx_name_long = ''; qx_trial_tag = 0; service_tel = ''; copyright_info = ''; copyright_info_PinYin = ''; // 区县中心地址 center_latitude = -1; // 区县中心纬度 center_longitude = -1; // 区县中心经度 } // 511528、兴文县 // int qx_code = 511528; // String qx_name = '宜宾市兴文'; // String service_tel = '\n服务热线:187-8467-8300'; // String copyright_info = '© ' + qx_name + '生态环境局 四川省踏石科技 版权所有' + service_tel; // String copyright_info_PinYin = 'YIBIN XINGWEN BLACK SMOKE CAR CAPTURE SYSTEM'; // // 兴文县中心地址:天泉商城 // double center_latitude = 28.29678023715008; // 区县中心纬度 // double center_longitude = 105.24189826141459; // 区县中心经度 // 注意:百度官方发布的城市中心点坐标是经度在前、纬度在后,必须对调才行,否则无法正确显示指定城市的地图 // BMFCoordinate BMFCoordinate(double latitude (纬度), double longitude (经度)) //中国领域一般经度大些 // center: BMFCoordinate(28.77914, 104.644079), //宜宾市翠屏白塔山 // 在点位地图中点击某个标注,在控制台会显示该标注的纬度和经度 // 兴文县中心位置:I/flutter (12538): mapPoi = {text: 半岛和居, pt: {latitude: 28.29678023715008, longitude: 105.24189826141459}, uid: b9e39ee2e8304f872fe67bcf} // 兴文县5个点位坐标 // 序号 选址位置 车道数量 经纬度 用途 // 1 古高路骨科医院附近 双向6车道 105.19762 28.334613 抓拍自长宁、江安、珙县方向和古宜高速入城黑烟车辆 // 2 高铁站附近 双向4车道 105.239899 28.337284 抓拍自泸州纳溪区方向入城黑烟车辆 // 3 大礼村附近 双向2车道 105.270567 28.285734 抓拍自泸州叙永县方向入城黑烟车辆 // 4 石海收费站附近 双向4车道 105.251038 28.287758 抓拍自古宜高速入城黑烟车辆 // 5 温水溪加油站附近 双向2车道 105.246259 28.286645 抓拍自云南威信县方向入城黑烟车辆 // 4、全局替换,将 ”hyzp_ybqx“全部替换为 ”hyzp_ybqx“,自动完成以下修改 // (1)、修改 R:\FlutterProject\FlutterProject51-hyzp_ybqx\hyzp_ybqx\pubspec.yaml 文件中的AppID,但存放目錄不變 // name: hyzp_ybqx // (2)、全局替换: // A、将 “com.flutter.hyzp_ybqx00_yibin” 全部替换为 “com.flutter.hyzp_ybqx” // B、将 “package:hyzp_ybqx00_yibin/” 全部替换为 “package:hyzp_ybqx/” // C、将 “# hyzp_ybqx00_yibin” 全部替换为 “# hyzp_ybqx” // D、将 “hyzp_ybqx00_yibin” 全部替换为 “hyzp_ybqx” // 5、完成以上修改后,打开 Android Studio 的终端窗口,切换到项目的 lib 目录下,运行 flutter clean // 6、重新编译运行App // end hyzp_ybqx-Commit022-区县切换新方法-OK //////////////////////////////////////////// //LED字幕信息 //String g_ledMessage = '绿水青山就是金山银山 宜宾市翠屏生态环境局宣。'; // 是否已经调用 FlutterDownloader.initialize(debug: true) bool bFlutterDownloader_initialize = false; bool bNewVer = false; //是否发现新版本 //处理延时登录,判断从网络获取三种统计数据是否完成 bool bMayLogin = true; //处理延时登录,判断是否已经点击登录按钮 bool bPreLoading = false; //处理延时登录,判断用户名登录是否验证通过 bool bLoginVerify = false; bool bHasMore = true; //part library //dart中,通过使用part、part of、library来实现拆分库,这样,就可以将一个庞大的库拆分成各种小库,只要引用主库即可 //点位总数 int dwSum = -1; Size sizeWindowPhysicalSize; //String dateAppCompile = '2020.12.30'; //1.0.1+1 //String dateAppCompile = '2021.02.20'; //1.2.5+1 //String dateAppCompile = '2021.03.18'; //1.2.6+1 //String dateAppCompile = '2021.05.18'; //1.2.7 List g_list = []; //正在获取点位视频标志,禁止重入 bool getingDwVideo = false; int getCount = 1; //获取点位视频地址尝试次数 int getSumTime = 0; //获取点位视频地址耗时(秒) int getingIndex = -1; //正在获取视频的点位的索引号 String getingDwmc = ''; //正在获取视频的点位名称 String urlnew = "http://www.yibinu.edu.cn/__local/5/35/DF/264049B7E978EEE2F5849688986_05D4A6FE_152CDB8C.mp4?e=.mp4"; bool isVideoUrl(String url, {bool showToast = false}) { print('url = $url'); if (0 == url.length) { return false; } String prefix = url.substring(0, 4); List list = ['http', 'rtmp', 'rstp']; for (String item in list) { if (prefix == item) { return true; } } if (showToast) { Fluttertoast.showToast( msg: '获取视频地址失败', toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.CENTER, ); } return false; } final TextEditingController myController = TextEditingController(); bool Playing = false; //禁止同时启动两次播放器 //final FijkPlayer player = FijkPlayer(); int g_iIndex = 0; PlayerRegionProvide playerRegionProvide; Future sysPop() async { // currentPos = player.currentPos.inMilliseconds; //seekto方法的参数是毫秒 // await writeCurrentPosFile(); // await player.stop(); await SystemChannels.platform.invokeMethod('SystemNavigator.pop'); } //人脸注册和人脸识别登录成功标志 int faceReg = -1; //1 成功,0 失败,-1 处理中 int faceLogin = -1; //1 成功,0 失败,-1 处理中 //人脸注册时所需用户ID int faceRegUserID = -1; //人脸注册时所需用户ID,-1 非法 List cameras; List g_users = new List(); //历史账号 bool g_can_expand_ListView = false; //是否能够打开历史账号 UserInfo g_userInfo = UserInfo(mapUserInfoRet: { "ret": 200, "data": { "is_login": true, "user_id": 152, "token": "959091E2A5E362E22F22F8DBE05737A95545A43AF28B19AB3DAD5F8557EE2E29", "qx_code": "511528", "qx_name": "兴文县", "sfsy": 0, //区县用户登录接口增加返回字段“sfsy”,0表示正式账号,1表示试用账号 }, "msg": "" }); // 去除末尾的区县 String trim_county(String _name) { return _name.substring(0, _name.length - 1); } Future getMapFromJson(var response) async { String _str = json.encode(response); Map _map = json.decode(_str); return _map; } // Future getVideoList(BuildContext context) async { // List assets = []; // return await MyAssetPicker.pickAssets( // context, // maxAssets: 1, // selectedAssets: assets, // requestType: RequestType.video, // ); // } Future getAndroidId() async { DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; //print('每个手机唯一的设备号:${androidInfo.androidId}'); // e.g. "Moto G (4)" g_userInfo.thisAndroidId = androidInfo.androidId; return g_userInfo.thisAndroidId; } // void playOrPause() { // playerRegionProvide.changePlayerState(bPlaying); // // if (bPlaying) { // player.start(); // } else { // player.pause(); // } // // Storage.setString('bFirstPlay', bFirstPlay ? 'true' : 'false'); // Storage.setString('bPlaying', bPlaying ? 'true' : 'false'); // // //updateFile(); // } // // void playAndPause() { // if (player.state == FijkState.started) { // bPlaying = false; // player.pause(); // } else if (player.state == FijkState.paused) { // bPlaying = true; // player.start(); // } // //setState(() {}); // playerRegionProvide.changePlayerState(bPlaying); // Storage.setString('bPlaying', bPlaying ? 'true' : 'false'); // } Alignment getAlignment(Offset offset, Size size) { // final double centerX = offset.dx / 2.0; // final double centerY = offset.dy / 2.0; //offset.dx = centerX + alignment.x * centerX; //double alignmentX = (0.0 == centerX) ? 0.0 : ((offset.dx - centerX) / centerX); double alignmentX = (offset.dx / size.width).clamp(-1.0, 1.0); //offset.dy = centerY + alignment.y * centerY; //double alignmentY = (0.0 == centerY) ? 0.0 : ((offset.dy - centerY) / centerY); double alignmentY = (offset.dy / size.height).clamp(-1.0, 1.0); // print('offset.dx = ${offset.dx}, offset.dy = ${offset.dy}'); print('Alignment.X = $alignmentX, Alignment.Y = $alignmentY'); return Alignment(alignmentX, alignmentY); } //flutter (dart)生成N位随机数 //https://blog.csdn.net/qq_36071410/article/details/101268640 // 庄童 2019-09-24 10:24:58 10271 收藏 String RandomBit(int len) { String scopeF = '123456789'; //首位 String scopeC = '0123456789'; //中间 String result = ''; for (int i = 0; i < len; i++) { if (i == 0) { result = scopeF[Random().nextInt(scopeF.length)]; } else { result = result + scopeC[Random().nextInt(scopeC.length)]; } } return result; } // sign=md5(ijddvzgEGaxbzsbmCtpdohxHyrAArwJB1003) // =3967eaebec0eed0642a1d395ac9293dd // String APPkey = 'ijddvzgEGaxbzsbmCtpdohxHyrAArwJB'; // 宜宾APPkey //Flutter对字符串进行MD5运算 发表于 2019-03-26 更新于 2020-12-04 分类于 Flutter 阅读次 String GenerateMd5(String str) { var content = new Utf8Encoder().convert(str); var md5 = crypto.md5; var digest = md5.convert(content); return hex.encode(digest.bytes); } //加载中的圈圈 Widget getMoreWidget2({ Color color = Colors.white, String text = '加载中...', double size = 30.0, double strokeWidth = 3.0, FontWeight fontWeight, double edge = 10.0, double height = 34, }) { return Center( child: Padding( padding: EdgeInsets.all(edge), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( height: size, width: size, child: CircularProgressIndicator( strokeWidth: strokeWidth, valueColor: AlwaysStoppedAnimation(color), ), ), SizedBox( height: ScreenUtil().setHeight(height), ), Text( text, textAlign: TextAlign.center, style: TextStyle( fontSize: size, // 文字大小 color: color, fontWeight: fontWeight, // 文字颜色 ), ), ], ), ), ); } //加载中的圈圈 Widget getMoreWidget({ String text = '加载中...', Color color = Colors.white, double size = 30.0, double strokeWidth = 3.0, TextAlign textAlign = TextAlign.left, }) { return Center( child: Padding( padding: EdgeInsets.all(10.0), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ SizedBox( height: size, width: size, child: CircularProgressIndicator( strokeWidth: strokeWidth, valueColor: AlwaysStoppedAnimation(color), ), ), SizedBox( height: 10, ), Text( text, textAlign: textAlign, style: TextStyle( fontSize: size, // 文字大小 color: color, ), ), ], ), ), ); } //自定义带说明图标按钮函数。点击说明文字有反应 Widget getIconAndTextButton( {IconData iconData, Color iconColor = Colors.black, var onPress = null}) { return Container( width: 50, height: 50, alignment: const Alignment(0, 0), child: FlatButton( padding: EdgeInsets.all(0), onPressed: onPress, //color: Colors.blue, color: Colors.transparent, //解决报错问题:FittedBox ← Expanded ← ConstrainedBox ← Container ← Center ← Padding ← // Container ← IconTheme ← Builder ← _PointerListener child: ConstrainedBox( constraints: BoxConstraints( maxHeight: 36, //最大高度 maxWidth: 36, //最大宽度 ), child: Padding( padding: EdgeInsets.only(top: 1), child: Icon(iconData, color: iconColor, size: 32), // child: Image.asset( // 'assets/images/left_arrow.png', // fit: BoxFit.fitWidth, // color: iconColor, // //fit: BoxFit.cover, // ), ), // child: Row( // mainAxisAlignment: MainAxisAlignment.center, // crossAxisAlignment: CrossAxisAlignment.end, // children: [ // Image.asset('assets/images/left_arrow.png', fit: BoxFit.cover), // // Expanded( // // //child: Icon(iconData, color: iconColor, size: 24), // // child: Image.asset('assets/images/left_arrow.png', fit: BoxFit.cover), // // ), // ], // ), ), //The offending Expanded is currently placed inside a ConstrainedBox widget. //The ownership chain for the RenderObject that received the incompatible parent data was: // FittedBox ← Expanded ← ConstrainedBox ← Container ← Center ← Padding ← Container ← IconTheme ← //Builder ← _PointerListener //The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a //RenderObject, which has been set up to accept ParentData of incompatible type ParentData. //Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, //Expanded widgets are placed directly inside Flex widgets. //The offending Expanded is currently placed inside a FittedBox widget. //The ownership chain for the RenderObject that received the incompatible parent data was: // ConstrainedBox ← Container ← Expanded ← FittedBox ← Center ← Padding ← Container ← IconTheme ← //Builder ← _PointerListener ← ⋯ // child: ConstrainedBox( // constraints: BoxConstraints( // maxHeight: 20, //最大高度 // maxWidth: 28, //最大宽度 // ), // child: Container( // child: Expanded( // child: new Icon(iconData, color: iconColor), // ), // ), // ), // child: ConstrainedBox( // constraints: BoxConstraints( // maxHeight: 30, //最大高度 // maxWidth: 38, //最大宽度 // minWidth: 38, //最大宽度 // ), // child: Row( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Expanded( // child: Icon(iconData, color: iconColor, size: 24), // ), // ], // ), // ), // child: Container( // width: 28, // height: 20, // child: Expanded( // child: new FittedBox( // fit: BoxFit.fill, // child: new Icon(iconData, color: iconColor), // ), // ), // ), // child: FittedBox( // fit: BoxFit.fitWidth, // alignment: Alignment.topLeft, // child: Container( // width: 28, // height: 20, // child: Expanded( // child: new FittedBox( // fit: BoxFit.fill, // child: new Icon(iconData, color: iconColor), // ), // ), // ), // ), ), ); } ///获取缩进空白符 String getDeepSpace(int deep) { var tab = StringBuffer(); for (int i = 0; i < deep; i++) { tab.write("\t"); } return tab.toString(); } // List map2list(Map _map) { // List _list = []; // _list = List.generate(listContacts2[widget.contactIndex].length, (index) { // String key = listContacts2[widget.contactIndex].keys.elementAt(index); // //return TextEditingController(text: listContacts2[widget.contactIndex][key]); // return TextEditingController(text: getUserText3(widget.contactIndex, key)); // }); // // } /// [object] 解析的对象 /// [deep] 递归的深度,用来获取缩进的空白长度 /// [isObject] 用来区分当前map或list是不是来自某个字段,则不用显示缩进。单纯的map或list需要添加缩进 String json_print(dynamic object, int deep, {bool isObject = false}) { var buffer = StringBuffer(); var nextDeep = deep + 1; if (object is Map) { var list = object.keys.toList(); if (!isObject) { //如果map来自某个字段,则不需要显示缩进 buffer.write("${getDeepSpace(deep)}"); } buffer.write("{"); if (list.isEmpty) { //当map为空,直接返回‘}’ buffer.write("}"); } else { buffer.write("\n"); for (int i = 0; i < list.length; i++) { buffer.write("${getDeepSpace(nextDeep)}\"${list[i]}\":"); buffer.write(json_print(object[list[i]], nextDeep, isObject: true)); if (i < list.length - 1) { buffer.write(","); buffer.write("\n"); } } buffer.write("\n"); buffer.write("${getDeepSpace(deep)}}"); } } else if (object is List) { if (!isObject) { //如果list来自某个字段,则不需要显示缩进 buffer.write("${getDeepSpace(deep)}"); } buffer.write("["); if (object.isEmpty) { //当list为空,直接返回‘]’ buffer.write("]"); } else { buffer.write("\n"); for (int i = 0; i < object.length; i++) { buffer.write(json_print(object[i], nextDeep)); if (i < object.length - 1) { buffer.write(","); buffer.write("\n"); } } buffer.write("\n"); buffer.write("${getDeepSpace(deep)}]"); } } else if (object is String) { //为字符串时,需要添加双引号并返回当前内容 buffer.write("\"$object\""); } else if (object is num || object is bool) { //为数字或者布尔值时,返回当前内容 buffer.write(object); } else { //如果对象为空,则返回null字符串 buffer.write("null"); } return buffer.toString(); } //人脸识别和上传的图片,都需要转换为 Base64 格式的字符串提交 //通过图片路径将图片转换成 Base64 字符串 Future image2Base64(String imagePath) async { File file = File(imagePath); List imageBytes = await file.readAsBytes(); String bs64 = base64Encode(imageBytes); String ext = getFileExtension(imagePath); print('imagePath = $imagePath, ext = $ext'); //String bs64Image = "data:image/png;base64," + bs64; String bs64Image = "data:image/${ext};base64," + bs64; return bs64Image; } //从字符路径 path 获取扩展名,不含点号 getFileExtension(String path) { //return path.substring(path.lastIndexOf('.')); //imagePath = /data/user/0/com.flutter.hyzp_ybqx/app_flutter/Pictures/flutter_test/1614662209478.jpg, ext = .jpg return path.substring(path.lastIndexOf('.') + 1); //不含点号 } //从字符路径 path 获取文件名(含扩展名) getFileName(String path) { //return path.substring(path.lastIndexOf('.')); //imagePath = /data/user/0/com.flutter.hyzp_ybqx/app_flutter/Pictures/flutter_test/1614662209478.jpg, ext = .jpg return path.substring(path.lastIndexOf('/') + 1); //不含点号 } Widget getBtnSizeX({@required text, double width = 70.0, double height = 40.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, ), ); } //返回主页ashamp // 博客园首页新随笔联系管理订阅订阅随笔 - 33 文章 - 0 评论 - 51 阅读 - 55018 // 在debug时使Flutter中的print打印json数据时更美观易读 // 为了避免deubg信息在生产环境打印,只在测试时打印,在main函数中,改变debugPrint的指向 // // 复制代码 // main(){ // if (Api.isDebug) { // debugPrint = (String message, {int wrapWidth}) { // try { // var object = json.decode(message); // message = JsonEncoder.withIndent(' ').convert(object); // } catch (e) {} // printWrapped(message); // }; // } else { // debugPrint = (String message, {int wrapWidth}) {}; // } // } // 复制代码 // 将printWrapped方法放入工具类或你需要的地方 // // void printWrapped(String text) { // final pattern = new RegExp('.{1,800}'); // 800 is the size of each chunk // pattern.allMatches(text).forEach((match) => developer.log(match.group(0))); // } // log方法需要引入 // // import 'dart:developer' as developer; // //在debug时使 Flutter 中的 print 打印 json 数据时更美观易读 void jsonPrint(String message, {int len = 800}) { //是否在生产环境 const bool isDebug = !const bool.fromEnvironment("dart.vm.product"); // if (!isDebug) { // return; // } try { var object = json.decode(message); message = JsonEncoder.withIndent(' ').convert(object); } catch (e) { print('e = $e'); } printWrapped(message); } // 打印长字符串 void printWrapped(String text, {int len = 800}) { final pattern = RegExp('.{1,$len}'); // 800 is the size of each chunk pattern.allMatches(text).forEach((match) => developer.log(match.group(0))); } //OK void my_segmentPrint(String str, {int len = 800}) { //是否在生产环境 const bool isDebug = !const bool.fromEnvironment("dart.vm.product"); if (!isDebug) { return; } List list = strToList(str); for (int i = 0; i < list.length; i++) { print('${list[i]}'); } } //OK List strToList(String str, {int len = 800}) { List strList = []; if (str.length <= len) { strList.add(str); } else { int splitCount = str.length ~/ len; //应该切割的次数 for (int i = 0; i < splitCount; i++) { strList.add(str.substring(len * i, len * (i + 1))); } //处理最后一段 if (str.length % len != 0) { strList.add(str.substring(len * splitCount)); } } print('strList:${strList.toString}'); return strList; } Widget getImageWidget() { return Container( alignment: Alignment(0, 0), height: ScreenUtil().setHeight(346), width: ScreenUtil().setWidth(942), decoration: BoxDecoration( image: DecorationImage(image: AssetImage('assets/images/装饰图片10.png'), fit: BoxFit.cover), ), child: Column( children: [ Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: ScreenUtil().setWidth(30), left: ScreenUtil().setWidth(55)), child: Text('改善城市空气质量', style: TextStyle(fontSize: 17, color: Colors.white)), ), Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(left: ScreenUtil().setWidth(55)), child: Text('建设长江生态第一城', style: TextStyle( fontSize: 19, color: Color.fromRGBO(49, 216, 123, 1), fontWeight: FontWeight.bold)), ), SizedBox(height: ScreenUtil().setHeight(copyright_info.contains('\n') ? 50 : 90)), Container( alignment: Alignment.center, child: Text(copyright_info, style: TextStyle(fontSize: 13, color: Color.fromRGBO(192, 192, 192, 1)), textAlign: TextAlign.center), ), ], ), // child: Image.asset( // 'assets/images/装饰图片10.png', // fit: BoxFit.cover, // ), ); } Widget getIconBtnSizeX( {@required text, width = 233, height = 116, onTop, Color color = Colors.black, double circular = 10, double textSize = 18}) { return InkWell( onTap: onTop, child: Container( alignment: Alignment(0, 0), margin: EdgeInsets.all(0), padding: EdgeInsets.all(0), width: ScreenUtil().setWidth(width), height: ScreenUtil().setHeight(height), decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(circular)), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox(width: ScreenUtil().setWidth(12)), Icon(Icons.play_arrow, color: Colors.white, size: ScreenUtil().setWidth(56)), Text( text, style: TextStyle(color: Colors.white, fontSize: textSize), ) ], ), ), ); }