- 20.flutter-表格
- html5表格标签
- 表格
- 2019-01-09第三天
- 2015年11月5日
- 2018-11-28
- 第5单元 个性月历
- 零基础Web前端开发(5)
- html基础
- HTML基础
///数据模型
///派车次数统计 2 class SendCarNumberList { List<String> titleList = []; //派车次数统计 List<SendCarNumberModel> sendCarList = []; //派车次数统计 int count1 = 0; //抽样 int count2 = 0; //还样 ///派车次数统计 2 SendCarNumberList.fromMap2(Map<String, dynamic> map) { if (map.isEmpty) return; this.titleList = _getTitleList(map["data"]); this.sendCarList = _getSendCarList(map["data"]); } ///派车次数统计 2 List<String> _getTitleList(Map<String, dynamic> map) { List<String> newList = List.from(map["titles"]); return newList; } ///派车次数统计 2 List<SendCarNumberModel> _getSendCarList(Map<String, dynamic> map) { List<SendCarNumberModel> newList = []; //CUM SendCarNumberModel model1 = SendCarNumberModel.fromMap(map["CUM"]); newList.add(model1); //抽样-CUM SendCarNumberModel model2 = SendCarNumberModel.fromMap(map["抽样"]["CUM"]); newList.add(model2); //抽样 List<dynamic> list2 = List.from(map["抽样"]["details"]); this.count1 = list2.length; list2.forEach((element) { if (element is Map<String, String>) { newList.add(SendCarNumberModel.fromMap(element)); } }); //还样-CUM SendCarNumberModel model3 = SendCarNumberModel.fromMap(map["还样"]["CUM"]); newList.add(model3); //还样 List<dynamic> list3 = List.from(map["还样"]["details"]); this.count2 = list3.length; list3.forEach((element) { if (element is Map<String, String>) { newList.add(SendCarNumberModel.fromMap(element)); } }); return newList; } } ///派车次数统计 2 class SendCarNumberModel { String a; String b; String c; String d; String e; String f; String g; String h; String i; String j; String k; SendCarNumberModel({this.a, this.b, this.c, this.d, this.e, this.f, this.g, this.h, this.i, this.j, this.k}); SendCarNumberModel.fromMap(Map<String, dynamic> map) { this.a = map["a"] != null ? map["a"].toString() : ""; this.b = map["b"] != null ? map["b"].toString() : ""; this.c = map["c"] != null ? map["c"].toString() : ""; this.d = map["d"] != null ? map["d"].toString() : ""; this.e = map["e"] != null ? map["e"].toString() : ""; this.f = map["f"] != null ? map["f"].toString() : ""; this.g = map["g"] != null ? map["g"].toString() : ""; this.h = map["h"] != null ? map["h"].toString() : ""; this.i = map["i"] != null ? map["i"].toString() : ""; this.j = map["j"] != null ? map["j"].toString() : ""; this.k = map["k"] != null ? map["k"].toString() : ""; } List<String> toList1() { List<String> list = []; list.add(a); list.add(b); list.add(c); return list; } List<String> toList2() { List<String> list = []; list.add(d); list.add(e); list.add(f); list.add(g); list.add(h); list.add(i); list.add(j); list.add(k); return list; } } ///派车次数统计 - 测试数据 2 var sendCarNumberTestData = { "error": 0, //0:正常;1:异常 "message": "success", //正常:success;异常:fail具体异常描述 "count": 0, "data": { "titles": ["2022", "2021", "Jul", "Aug", "WK32", "WK31", "08/12", "08/11"], "CUM": { "a": "CUM", //派车 "b": "CUM", //始发 "c": "CUM", //接收 "d": "12956", //今年 "e": "12565", //上一年 "f": "126", //今月 "g": "125", //上一月 "h": "26", //今周 "i": "30", //上一周 "j": "10", //今天 "k": "6", //上一天 }, "抽样": { "CUM": { "a": "抽样", //派车 "b": "CUM", //始发 "c": "CUM", //接收 "d": "1295", //今年 "e": "1255", //上一年 "f": "12", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "2", //上一天 }, "details": [ { "a": "抽样", //派车 "b": "C09V", //始发 "c": "G11", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "抽样", //派车 "b": "C06V", //始发 "c": "G112", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "抽样", //派车 "b": "C09V", //始发 "c": "G11", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "抽样", //派车 "b": "C06V", //始发 "c": "G112", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, ], }, "还样": { "CUM": { "a": "还样", //派车 "b": "CUM", //始发 "c": "CUM", //接收 "d": "1295", //今年 "e": "1255", //上一年 "f": "12", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "2", //上一天 }, "details": [ { "a": "还样", //派车 "b": "C09V", //始发 "c": "G11", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "还样", //派车 "b": "C06V", //始发 "c": "G112", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "还样", //派车 "b": "C09V", //始发 "c": "G11", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, { "a": "还样", //派车 "b": "C06V", //始发 "c": "G112", //接收 "d": "1256", //今年 "e": "1265", //上一年 "f": "16", //今月 "g": "15", //上一月 "h": "6", //今周 "i": "3", //上一周 "j": "1", //今天 "k": "6", //上一天 }, ], }, } };
界面实现
import 'package:flutter/material.dart'; import 'package:flutter_table/tools/custom_calendar_widget.dart'; import 'package:flutter_table/tools/layout.dart'; import 'package:flutter_table/tools/logs.dart'; import 'package:flutter_table/tools/name_color_widget.dart'; import 'package:flutter_table/tools/public_widget.dart'; import 'package:linked_scroll_controller/linked_scroll_controller.dart'; import 'data_statistics_chart_model.dart'; ///派車次數統計(次)3 class SendCarNumberPage extends StatefulWidget { final String title; //派車次數統計 const SendCarNumberPage({Key key, @required this.title}) : super(key: key); @override State<SendCarNumberPage> createState() => _SendCarNumberPageState(); } ///Chaos20200829 class _SendCarNumberPageState extends State<SendCarNumberPage> { //选择时间 String _selectTime = ""; //固定区域数据 List<String> _fixedAreas = ["派车", "始发", "接收"]; //左边列表数据 List<SendCarNumberModel> _leftList = []; //右边标题数据 List<String> _rightTitles = ["2022", "2021", "Jul", "Aug", "WK32", "WK31", "08/12", "08/11"]; //右边列表数据 List<SendCarNumberModel> _rightList = []; double _fixedAreaWidth = 150; //固定区域宽 double _fixedAreaHeight = 40; //固定区域高 double _itemWidth = 50; // item宽度 double _itemHeight = 40; // item长度 ScrollController _leftController; //左边数据-上下滚动控制器 ScrollController _rightTitleController; //右边标题-左右滚动控制器 ScrollController _rowController; //右边数据-左右滚动控制器 ScrollController _columnController; //右边数据-上下滚动控制器 LinkedScrollControllerGroup _verticalControllers; //垂直滚动同步 LinkedScrollControllerGroup _horizontalControllers; //水平滚动同步 int _count1 = 0; //抽样数据个数 int _count2 = 0; //还样数据个数 ///init @override void initState() { super.initState(); //现在的时间 _selectTime = DateTime.now().toString().split(".").first.split(" ").first; //初始化控制器配置 _initController(); //数据 _getData(); } ///dispose @override void dispose() { //销毁控制器 _disposeController(); super.dispose(); } ///build @override Widget build(BuildContext context) { return Container( width: double.infinity, height: w(50) + ((_rightList.length + 1) * w(40) + w(20) < w(385) ? (_rightList.length + 1) * w(40) + w(20) : w(385)), color: Colors.white, padding: EdgeInsets.symmetric(horizontal: w(16)), child: Column( children: [ _getTopWidget(widget.title, "images/iqc_sampling_sys/icon-data434.png"), Expanded(child: _getForm()), Container(height: w(20), color: Colors.white), ], ), ); } //界面.. ///标题+时间选择 0 _getTopWidget(String title, String imagePath) { return Container( width: double.infinity, height: w(50), alignment: Alignment.center, color: Colors.white, child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ getTitle("$title(次)", Color(0xff000000), sp(18), fontWeight: FontWeight.bold), _getTextImage(imagePath, _selectTime), ], ), ); } ///时间选择 0 _getTextImage(String imagePath, String title) { return InkWell( onTap: () { logs("选择时间..."); _showCalendar(); }, child: getTextImage(imagePath, title), ); } ///弹窗-日历 0 _showCalendar() { return showDialog( context: context, barrierColor: Color(0x66000000), builder: (context) { return Scaffold( backgroundColor: Colors.transparent, body: CustomCalendarWidget( callBack: (value) { //选择的时间 _selectTime = value.split(" ").first; setState(() {}); }, ), ); }); } ///表格 1 _getForm() { return Row( children: [ //左边 _getLeftForm(), //右边 Expanded( child: _getRightForm(), ), ], ); } ///左边表格 1.1 _getLeftForm() { return Container( width: _fixedAreaWidth, child: Column( children: [ //固定区域标题 Container( width: _fixedAreaWidth, height: _fixedAreaHeight, child: _tabRowLeft(-1, _fixedAreas), ), //左边-上下滑动区域 Expanded( child: ListView.builder( controller: _leftController, scrollDirection: Axis.vertical, //垂直滚动 physics: BouncingScrollPhysics(), padding: EdgeInsets.zero, itemCount: _leftList.length, itemBuilder: (context, index) { return index == 0 ? _tabRowCUM(0, _leftList[0].toList1()[2], 3) : _tabRowLeft(index, _leftList[index].toList1(), isTitle: false); }, ), ), ], ), ); } ///每行 1.1 _tabRowLeft( int index, //下标 List<String> data, //数组 { bool isTitle = true, }) { var widget; //始发=接收 if (data[1] == data[2]) { widget = Row( children: [ _tabRowCUM(index, "", 1), _tabRowCUM(index, data[2], 2), ], ); } //始发!=接收 else { widget = Row( children: data.asMap().keys.map((i) { String value = ""; if (i == 0) { if (index == 1 + _count1 / 2 || index == 2 + _count1 + _count2 / 2) { value = data[i]; } else if (index == -1) { value = data[i]; } } else { value = data[i]; } return Container( width: w(50), height: w(40), alignment: Alignment.center, decoration: BoxDecoration( color: i == 0 ? Color(0xffc2d7ff) : Colors.transparent, border: Border( right: BorderSide(color: i == 7 ? Colors.transparent : Color.fromRGBO(255, 255, 255, 0.53), width: w(1)), bottom: BorderSide( color: index == 1 + _count1 && i == 0 ? Colors.white : Colors.transparent, width: w(2), ), ), ), child: Text( value, textAlign: TextAlign.center, maxLines: 2, style: TextStyle(fontSize: sp(16), color: isTitle ? Color(0xd6333333) : Color(0xff333333)), ), ); }).toList(), ); } //返回 return Container( decoration: BoxDecoration( color: index == -1 ? Color(0xffc2d7ff) : index % 2 == 0 ? Color.fromRGBO(236, 242, 250, 0.46) : Color(0xffecf2fa), ), child: widget, ); } ///CUM 1.1 _tabRowCUM(int index, String value, int count) { return Container( width: w(50) * count, height: w(40), alignment: Alignment.center, decoration: BoxDecoration( color: count == 3 ? Color.fromRGBO(236, 242, 250, 0.46) : value.isEmpty ? Color(0xffc2d7ff) : index % 2 == 0 ? Colors.transparent : Color(0xffecf2fa), border: Border( right: BorderSide(color: Color.fromRGBO(255, 255, 255, 0.53), width: w(1)), ), ), child: Text( value, textAlign: TextAlign.center, maxLines: 2, style: TextStyle(fontSize: sp(16), color: Color(0xff333333)), ), ); } ///右边表格 1.2 _getRightForm() { return Column( children: [ //右边标题-左右滚动区域 Container( width: _itemWidth * _rightTitles.length, height: _itemHeight, child: ListView.builder( controller: _rightTitleController, scrollDirection: Axis.horizontal, //水平滚动 physics: BouncingScrollPhysics(), padding: EdgeInsets.zero, itemCount: _rightTitles.length, itemBuilder: (context, index) { return _tabItemRight(index, _rightTitles[index]); }, ), ), //右边-上下-左右-滚动区域 Expanded( child: ListView( controller: _rowController, scrollDirection: Axis.horizontal, //水平滚动 physics: BouncingScrollPhysics(), padding: EdgeInsets.zero, children: [ Container( width: _itemWidth * _rightList[0].toList2().length, child: ListView.builder( controller: _columnController, scrollDirection: Axis.vertical, //垂直滚动 physics: BouncingScrollPhysics(), padding: EdgeInsets.zero, itemCount: _rightList.length, itemBuilder: (context, index) { return _tabRowRight(index, _rightList[index].toList2(), isTitle: false); }, ), ) ], ), ), ], ); } ///每行 1.2 _tabRowRight( int index, //下标 List<String> data, //数组 { bool isTitle = true, }) { return Container( decoration: BoxDecoration( color: index == -1 ? Color(0xffc2d7ff) : index % 2 == 0 ? Color.fromRGBO(236, 242, 250, 0.46) : Color(0xffecf2fa), ), child: Row( children: data.asMap().keys.map((i) { return Container( width: w(50), height: w(40), alignment: Alignment.center, decoration: BoxDecoration( border: Border( right: BorderSide(color: i == 7 ? Colors.transparent : Color.fromRGBO(255, 255, 255, 0.53), width: w(1)), ), ), child: Text( data[i].toString(), textAlign: TextAlign.center, maxLines: 2, style: TextStyle(fontSize: sp(16), color: isTitle ? Color(0xd6333333) : Color(0xff333333)), ), ); }).toList(), ), ); } ///每个 1.2 _tabItemRight( int i, //下标 String value, //值 { bool isTitle = true, }) { return Container( width: w(50), height: w(40), alignment: Alignment.center, decoration: BoxDecoration( color: Color(0xffc2d7ff), border: Border( right: BorderSide(color: i == 7 ? Colors.transparent : Color.fromRGBO(255, 255, 255, 0.53), width: w(1)), ), ), child: Text( value.toString(), textAlign: TextAlign.center, maxLines: 2, style: TextStyle(fontSize: sp(16), color: isTitle ? Color(0xd6333333) : Color(0xff333333)), ), ); } //事件.. ///初始化控制器配置 _initController() { _fixedAreaWidth = w(150); //固定区域宽 _fixedAreaHeight = w(40); //固定区域高 _itemWidth = w(50); // item宽度 _itemHeight = w(40); // item高度 //水平滚动同步 _horizontalControllers = LinkedScrollControllerGroup(); _rightTitleController = _horizontalControllers?.addAndGet(); _rowController = _horizontalControllers?.addAndGet(); //垂直滚动同步 _verticalControllers = LinkedScrollControllerGroup(); _leftController = _verticalControllers?.addAndGet(); _columnController = _verticalControllers?.addAndGet(); } ///销毁控制器 _disposeController() { _leftController?.dispose(); _rightTitleController?.dispose(); _rowController?.dispose(); _columnController?.dispose(); } //数据... ///数据 _getData() { SendCarNumberList model = SendCarNumberList.fromMap2(sendCarNumberTestData); _leftList = model.sendCarList; _rightTitles = model.titleList; _rightList = model.sendCarList; _count1 = model.count1; _count2 = model.count2; } }
linked_scroll_controller: ^0.2.0 #引入列表同步滚动
import 'package:flutter/material.dart'; import 'package:linked_scroll_controller/linked_scroll_controller.dart'; //固定标题的滑动 class TimeTablePage extends StatefulWidget { const TimeTablePage({Key key}) : super(key: key); @override _TimeTablePageState createState() => _TimeTablePageState(); } class _TimeTablePageState extends State<TimeTablePage> { int rowsCount = 100; //左边标题的个数 int columnsCount = 30; //右边标题的个数 double cellWidth = 80; // item宽度 double cellHeight = 50; // item长度 ScrollController leftController; //左边标题 ScrollController topController; //右边标题 ScrollController rowController; //数据 List<ScrollController> columnsController = []; LinkedScrollControllerGroup _verticalControllers; LinkedScrollControllerGroup _horizontalControllers; ///init @override void initState() { super.initState(); //初始化控制器配置 _initController(); } ///dispose @override void dispose() { //销毁控制器 _disposeController(); super.dispose(); } ///build @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("工时表"), ), body: _bodyWidget(), ); } //界面... ///表格 _bodyWidget() { return Row( children: [ //左边 Container( width: cellWidth, child: Column( children: [ //时间 姓名 Container( decoration: BoxDecoration( color: Colors.blueGrey[100], border: Border.all(color: Color(0xffeeeeee), width: 1), ), padding: EdgeInsets.only(left: 5.0, right: 5.0), height: cellHeight, width: cellWidth, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( alignment: Alignment.topRight, child: Text("时间"), ), Container(alignment: Alignment.bottomLeft, child: Text("姓名")) ], ), ), //左边的标题 Expanded( child: ListView.builder( controller: leftController, scrollDirection: Axis.vertical, padding: EdgeInsets.all(0), itemBuilder: (context, index) { return Container( decoration: BoxDecoration( color: Colors.blueGrey[100], border: Border.all(color: Color(0xffeeeeee), width: 1), ), height: cellHeight, child: Center(child: Text("张${index + 1}"))); }, itemCount: rowsCount - 1, ), ), ], ), ), //右边 Expanded( child: Column( children: [ //右边标题 Container( height: cellHeight, child: ListView.builder( controller: topController, padding: EdgeInsets.all(0), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return Container( decoration: BoxDecoration( color: Colors.blueGrey[100], border: Border.all(color: Color(0xffeeeeee), width: 1), ), width: cellWidth, child: Center(child: Text("8月${index + 1}日"))); }, itemCount: columnsCount, ), ), //右边数据 Expanded( child: ListView.builder( controller: rowController, padding: EdgeInsets.all(0), scrollDirection: Axis.horizontal, itemBuilder: (context, index) { return Container( width: cellWidth, child: ListView.builder( controller: columnsController[index], scrollDirection: Axis.vertical, shrinkWrap: true, padding: EdgeInsets.all(0), itemBuilder: (context, innerIndex) { return Container(height: cellHeight, child: Center(child: Text("$innerIndex, $index"))); }, itemCount: rowsCount - 1, ), ); }, itemCount: columnsCount, ), ) ], ), ), ], ); } //事件... ///初始化控制器配置 _initController() { //水平同步滚动 _horizontalControllers = LinkedScrollControllerGroup(); topController = _horizontalControllers?.addAndGet(); rowController = _horizontalControllers?.addAndGet(); //垂直同步滚动 _verticalControllers = LinkedScrollControllerGroup(); leftController = _verticalControllers?.addAndGet(); for (var i = 0; i < columnsCount; i++) { ScrollController columnController = _verticalControllers?.addAndGet(); if (columnController != null) { columnsController.add(columnController); } } } ///销毁控制器 _disposeController() { leftController?.dispose(); topController?.dispose(); rowController?.dispose(); for (var controller in columnsController) { controller.dispose(); } } }
网友评论