data_detail.dart 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. import 'package:application/view/home/data_detail/data_detail_bar_charts.dart';
  2. import 'package:application/view/home/data_detail/data_detail_cp.dart';
  3. import 'package:application/widget.dart';
  4. import 'package:common_pub/model/history_detail.dart';
  5. import 'package:common_pub/ui/history_detail/trace_bar.dart';
  6. import 'package:common_pub/ui/map_view/map_view.dart';
  7. import 'package:common_pub/ui/map_view/view_map_cp.dart';
  8. import 'package:common_pub/ui/map_view/view_map_image.dart';
  9. import 'package:common_pub/ui/map_view/view_map_touch.dart';
  10. import 'package:common_pub/ui/map_view/view_map_trace.dart';
  11. import 'package:common_pub/ui/map_view/view_plug_loading.dart';
  12. import 'data_detail_controller.dart';
  13. class DataDetailPage extends StatelessWidget {
  14. const DataDetailPage({super.key});
  15. @override
  16. Widget build(BuildContext context) {
  17. return GetBuilder(
  18. init: DataDetailController(),
  19. builder: (c) {
  20. return Container(
  21. height: double.infinity,
  22. width: double.infinity,
  23. color: const Color(0xffc9c0c0),
  24. alignment: Alignment.center,
  25. child: c.mapWatch != null
  26. ? content(context, c.mapWatch!, c)
  27. : noData());
  28. });
  29. }
  30. Widget noData() {
  31. return Center(
  32. child: Column(
  33. mainAxisSize: MainAxisSize.min,
  34. children: [
  35. Image.asset(Assets.imagesIcNoData, height: 64),
  36. const SizedBox(height: 25),
  37. const Text('没有数据, 请选择地图',
  38. style: TextStyle(color: Color(0xff707070), fontSize: 18.5)),
  39. ],
  40. ),
  41. );
  42. }
  43. static const cpColor = Color(0xffcc00ff);
  44. Widget content(
  45. BuildContext context, MapWatchService map, DataDetailController c) {
  46. return Obx(() {
  47. final children = <Widget>[
  48. ViewPlugLoading(map.plugMap),
  49. ViewMapImage(map.plugMap),
  50. ];
  51. final data = c.selectedDetail.value;
  52. if (data != null) {
  53. children.add(ViewMapCP(
  54. map.plugMap,
  55. cpWantAndHistoryList: data.controlPoints,
  56. isHideRouteBeforeStart: false,
  57. isShowPath: false,
  58. cpTheme: ViewMapCPTheme()
  59. ..cpJumpColor = cpColor
  60. ..cpPunchedColor = cpColor,
  61. ));
  62. children.add(ViewMapTrace(map.plugMap, data.traceList,
  63. controller: c.viewMapTraceController));
  64. }
  65. children.add(ViewMapTouch(map.plugMap));
  66. return Row(children: [
  67. Expanded(
  68. child: Column(
  69. children: [
  70. Expanded(
  71. child: ViewMapStack(plug: map.plugMap, children: children)),
  72. _traceBarView(c)
  73. ],
  74. )),
  75. _UserListView()
  76. ]);
  77. });
  78. }
  79. Widget _traceBarView(DataDetailController c) {
  80. final detail = c.selectedDetail.value;
  81. final children = <Widget>[];
  82. if (detail != null) {
  83. final data =
  84. detail.traceList.map((e) => TraceBarData(e.pace)..ts = e.ts).toList();
  85. children.addAll([
  86. const SizedBox(height: 8),
  87. const Text('配速(按时间)'),
  88. TraceBar(
  89. data,
  90. controller: c.traceBarController,
  91. direction: Axis.horizontal,
  92. trackWidth: 10,
  93. paddingStart: 100,
  94. paddingEnd: 100,
  95. mask: true,
  96. isShowCp: true,
  97. cpList: detail.controlPoints,
  98. ),
  99. ]);
  100. }
  101. return Container(
  102. decoration: const BoxDecoration(color: Colors.white),
  103. height: 73,
  104. width: double.infinity,
  105. child: Column(children: children),
  106. );
  107. }
  108. }
  109. class _UserListView extends GetView<DataDetailController> {
  110. @override
  111. Widget build(BuildContext context) {
  112. return Obx(() {
  113. return Container(
  114. width: 263,
  115. height: double.infinity,
  116. decoration: const BoxDecoration(color: Colors.white, boxShadow: [
  117. BoxShadow(color: Color(0x33000000), blurRadius: 4.3)
  118. ]),
  119. padding: const EdgeInsets.all(20),
  120. child: Column(
  121. children: [
  122. Row(
  123. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  124. children: [
  125. const Text('用户列表'),
  126. IconButton(
  127. onPressed: controller.selectedDetail.value != null
  128. ? () => controller.showDetail.value =
  129. !controller.showDetail.value
  130. : null,
  131. icon: const Icon(Icons.more_horiz)),
  132. ],
  133. ),
  134. Expanded(
  135. child: ListView(
  136. children: controller.showDetail.value
  137. ? _detailView()
  138. : controller.userList
  139. .map((element) => _userElem(element))
  140. .toList(),
  141. ))
  142. ],
  143. ));
  144. });
  145. }
  146. List<Widget> _detailView() {
  147. final detail = controller.selectedDetail.value!;
  148. return [
  149. DataDetailCP(cpList: detail.controlPoints),
  150. const SizedBox(height: 8),
  151. const DataDetailBarCharts(),
  152. ];
  153. }
  154. Widget _userElem(UserInfo data) {
  155. return Obx(() {
  156. final children = <Widget>[
  157. Container(
  158. width: double.infinity,
  159. height: 42,
  160. margin: const EdgeInsets.only(top: 8),
  161. padding: const EdgeInsets.only(left: 4),
  162. decoration: BoxDecoration(
  163. color: Colors.white,
  164. boxShadow: const [
  165. BoxShadow(color: Color(0x29000000), blurRadius: 3)
  166. ],
  167. borderRadius: BorderRadius.circular(3.56)),
  168. child: Row(
  169. children: [
  170. Container(
  171. height: double.infinity,
  172. width: 3.56,
  173. margin: const EdgeInsets.only(top: 8, bottom: 8, right: 3.55),
  174. decoration: BoxDecoration(
  175. color: data.data.oId == controller.selectedUserId.value
  176. ? Colors.orange
  177. : Colors.transparent,
  178. borderRadius: BorderRadius.circular(2.1)),
  179. ),
  180. Text(data.data.oName),
  181. const Spacer(),
  182. IconButton(
  183. onPressed: () {
  184. data.isExpand.value = !data.isExpand.value;
  185. },
  186. icon: Icon(data.isExpand.value
  187. ? Icons.arrow_drop_up
  188. : Icons.arrow_drop_down))
  189. ],
  190. ),
  191. )
  192. ];
  193. if (data.isExpand.value) {
  194. children.add(Column(
  195. children: data.data.list
  196. .map((element) => GestureDetector(
  197. onTap: () => controller.selectDetail(element, data),
  198. child: detailElem(element)))
  199. .toList(),
  200. ));
  201. }
  202. return Column(
  203. children: children,
  204. );
  205. });
  206. }
  207. Widget detailElem(DetailSimple detail) {
  208. return Container(
  209. margin: const EdgeInsets.only(left: 12, top: 2, bottom: 4),
  210. width: double.infinity,
  211. height: 54,
  212. padding: const EdgeInsets.fromLTRB(4, 6, 4, 6),
  213. decoration: BoxDecoration(
  214. color: Colors.white,
  215. borderRadius: BorderRadius.circular(3.5),
  216. boxShadow: const [
  217. BoxShadow(color: Color(0x33000000), blurRadius: 1.3)
  218. ]),
  219. child: Row(
  220. children: [
  221. Container(
  222. height: double.infinity,
  223. width: 3.56,
  224. margin: const EdgeInsets.only(right: 3.55),
  225. decoration: BoxDecoration(
  226. color: detail.gameId ==
  227. controller.selectedDetailSimple.value.gameId
  228. ? Colors.orange
  229. : Colors.transparent,
  230. borderRadius: BorderRadius.circular(2.1)),
  231. ),
  232. Expanded(
  233. child: Column(
  234. crossAxisAlignment: CrossAxisAlignment.start,
  235. children: [
  236. Text(detail.courseName,
  237. maxLines: 1, overflow: TextOverflow.ellipsis),
  238. Text(
  239. detail.actName,
  240. maxLines: 1,
  241. overflow: TextOverflow.ellipsis,
  242. ),
  243. ],
  244. )),
  245. const SizedBox(width: 12),
  246. Text(detail.isComplete ? '完赛' : '未完赛')
  247. ],
  248. ),
  249. );
  250. }
  251. }