track_daily_item.dart 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import 'dart:math';
  2. import 'package:flutter/cupertino.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:location/data/bean/track_daily_bean.dart';
  5. import 'package:location/data/consts/constants.dart';
  6. import 'package:location/module/track/track_util.dart';
  7. import 'package:location/resource/assets.gen.dart';
  8. import 'package:location/resource/colors.gen.dart';
  9. import 'package:location/resource/string.gen.dart';
  10. import 'package:location/utils/common_expand.dart';
  11. import 'package:location/utils/date_util.dart';
  12. import '../track_status.dart';
  13. Widget buildTrackDailyItem(TrackDailyBean bean, bool isEnd) {
  14. return Container(
  15. padding: EdgeInsets.symmetric(horizontal: 12.w),
  16. margin: EdgeInsets.only(bottom: 8.w),
  17. child: Column(
  18. crossAxisAlignment: CrossAxisAlignment.start,
  19. children: [
  20. Builder(builder: (context) {
  21. if (bean.status == TrackStatus.moving) {
  22. return _buildMovingTrackDailyItem(bean);
  23. } else if (bean.status == TrackStatus.stay) {
  24. return _buildStayTrackDailyItem(bean);
  25. } else if (bean.status == TrackStatus.abnormal) {
  26. return _buildAbnormalTrackDailyItem(bean);
  27. } else {
  28. return SizedBox(height: 50.w, child: Text('未知轨迹,请更新最新应用版本'));
  29. }
  30. }),
  31. if (isEnd) _buildEndPoint(bean)
  32. ],
  33. ),
  34. );
  35. }
  36. Widget _buildMovingTrackDailyItem(TrackDailyBean bean) {
  37. return Column(
  38. crossAxisAlignment: CrossAxisAlignment.start,
  39. children: [
  40. IntrinsicHeight(
  41. child: Row(
  42. children: [
  43. Column(
  44. crossAxisAlignment: CrossAxisAlignment.center,
  45. children: [
  46. _buildTimeText(bean.start),
  47. SizedBox(height: 4.w),
  48. _buildRingView(),
  49. SizedBox(height: 4.w),
  50. Expanded(
  51. child: Container(
  52. width: 1.w,
  53. decoration: BoxDecoration(
  54. color: '#F0F0F0'.color,
  55. borderRadius: BorderRadius.circular(100.r),
  56. ),
  57. ),
  58. )
  59. ],
  60. ),
  61. Expanded(
  62. child: Container(
  63. height: 50.w,
  64. margin: EdgeInsets.only(top: 26.w),
  65. decoration: BoxDecoration(
  66. borderRadius: BorderRadius.circular(8.r),
  67. gradient: LinearGradient(colors: [
  68. '#F8F5FF'.color,
  69. ColorName.transparent,
  70. ])),
  71. padding: EdgeInsets.symmetric(horizontal: 14.w),
  72. child: Row(
  73. children: [
  74. Assets.images.iconTrackMoving.image(width: 16.w),
  75. SizedBox(width: 5.w),
  76. Text(
  77. StringName.trackDetailMoving,
  78. style: TextStyle(
  79. fontSize: 12.sp,
  80. color: '#333333'.color,
  81. fontWeight: FontWeight.bold),
  82. )
  83. ],
  84. ),
  85. ))
  86. ],
  87. ),
  88. ),
  89. SizedBox(height: 8.w),
  90. ],
  91. );
  92. }
  93. Widget _buildStayTrackDailyItem(TrackDailyBean bean) {
  94. return Column(
  95. crossAxisAlignment: CrossAxisAlignment.start,
  96. children: [
  97. IntrinsicHeight(
  98. child: Row(
  99. children: [
  100. Column(
  101. crossAxisAlignment: CrossAxisAlignment.center,
  102. children: [
  103. _buildTimeText(bean.start),
  104. SizedBox(height: 4.w),
  105. _buildRingView(),
  106. SizedBox(height: 4.w),
  107. Expanded(
  108. child: Container(
  109. width: 1.w,
  110. decoration: BoxDecoration(
  111. color: '#F0F0F0'.color,
  112. borderRadius: BorderRadius.circular(100.r),
  113. ),
  114. ),
  115. )
  116. ],
  117. ),
  118. Expanded(
  119. child: Container(
  120. padding: EdgeInsets.all(10.w),
  121. margin: EdgeInsets.only(top: 20.w),
  122. decoration: BoxDecoration(
  123. borderRadius: BorderRadius.circular(8.r),
  124. gradient: LinearGradient(colors: [
  125. '#F8F5FF'.color,
  126. ColorName.transparent,
  127. ])),
  128. child: ConstrainedBox(
  129. constraints: BoxConstraints(minHeight: 60.w),
  130. child: Column(
  131. crossAxisAlignment: CrossAxisAlignment.start,
  132. children: [
  133. Expanded(
  134. child: Text(
  135. bean.addr ?? '',
  136. style: TextStyle(
  137. fontSize: 12.sp,
  138. color: '#333333'.color,
  139. fontWeight: FontWeight.bold),
  140. ),
  141. ),
  142. SizedBox(height: 11.w),
  143. Row(
  144. children: [
  145. _buildStayDesc(bean.duration),
  146. SizedBox(width: 18.w),
  147. _buildLockDesc(bean.highUnlock, bean.totalUnlock),
  148. SizedBox(width: 18.w),
  149. Expanded(child: _buildNetDesc(bean.network))
  150. ],
  151. )
  152. ],
  153. ),
  154. ),
  155. ))
  156. ],
  157. ),
  158. ),
  159. SizedBox(height: 8.w),
  160. ],
  161. );
  162. }
  163. Widget _buildAbnormalTrackDailyItem(TrackDailyBean bean) {
  164. return Column(
  165. crossAxisAlignment: CrossAxisAlignment.start,
  166. children: [
  167. IntrinsicHeight(
  168. child: Row(
  169. children: [
  170. Column(
  171. crossAxisAlignment: CrossAxisAlignment.center,
  172. children: [
  173. _buildTimeText(bean.start),
  174. SizedBox(height: 4.w),
  175. _buildRingView(isError: true),
  176. SizedBox(height: 4.w),
  177. Expanded(
  178. child: Container(
  179. width: 1.w,
  180. decoration: BoxDecoration(
  181. color: '#F0F0F0'.color,
  182. borderRadius: BorderRadius.circular(100.r),
  183. ),
  184. ),
  185. )
  186. ],
  187. ),
  188. Expanded(
  189. child: Container(
  190. height: 50.w,
  191. padding: EdgeInsets.all(10.w),
  192. margin: EdgeInsets.only(top: 41.w, bottom: 7.w),
  193. decoration: BoxDecoration(
  194. borderRadius: BorderRadius.circular(8.r),
  195. gradient: LinearGradient(colors: [
  196. '#FFECEC'.color,
  197. ColorName.white,
  198. ])),
  199. child: Row(
  200. children: [
  201. Assets.images.iconTrackError.image(width: 19.4.w),
  202. SizedBox(width: 5.5.w),
  203. Text(StringName.trackDetailError,
  204. style: TextStyle(
  205. fontSize: 12.sp,
  206. color: '#333333'.color,
  207. fontWeight: FontWeight.bold)),
  208. SizedBox(width: 10.w),
  209. Spacer(),
  210. Assets.images.imgTrackAiAnalyse.image(width: 73.w),
  211. SizedBox(width: 6.w),
  212. ],
  213. ),
  214. ))
  215. ],
  216. ),
  217. ),
  218. SizedBox(height: 8.w),
  219. ],
  220. );
  221. }
  222. Widget _buildRingView({bool isError = false}) {
  223. return Container(
  224. width: 12.w,
  225. height: 12.w,
  226. decoration: BoxDecoration(
  227. shape: BoxShape.circle,
  228. border: Border.all(
  229. color: isError ? '#F24D4D'.color : '#66999999'.color,
  230. width: isError ? 2.w : 1.w,
  231. ),
  232. ),
  233. );
  234. }
  235. Widget _buildTimeText(int time) {
  236. return Text(
  237. DateUtil.fromMillisecondsSinceEpoch('HH:mm', time),
  238. style: TextStyle(
  239. fontSize: 12.sp, color: '#333333'.color, fontWeight: FontWeight.w500),
  240. );
  241. }
  242. Widget _buildEndPoint(TrackDailyBean bean) {
  243. return Column(
  244. children: [
  245. SizedBox(height: 4.w),
  246. _buildRingView(),
  247. SizedBox(height: 4.w),
  248. _buildTimeText(bean.end),
  249. ],
  250. );
  251. }
  252. Widget _buildNetDesc(String? network) {
  253. bool isMobile = network == Constants.kMobileNetworkTag;
  254. return IntrinsicWidth(
  255. child: Row(
  256. children: [
  257. isMobile
  258. ? Assets.images.iconNetMobile.image(width: 14.w, height: 14.w)
  259. : Assets.images.iconNetWifi.image(width: 14.w, height: 14.w),
  260. SizedBox(width: 2.w),
  261. Expanded(
  262. child: Text(
  263. isMobile ? StringName.trackDetailMobile : network ?? '',
  264. style:
  265. TextStyle(fontSize: 11.sp, color: '#666666'.color, height: 1),
  266. ),
  267. )
  268. ],
  269. ),
  270. );
  271. }
  272. Widget _buildLockDesc(int? highUnlock, int? totalUnlock) {
  273. if ((highUnlock == null && totalUnlock == null) ||
  274. (highUnlock == 0 && totalUnlock == 0)) {
  275. return Row(
  276. children: [
  277. Assets.images.iconTrackUnlockNoPermission
  278. .image(width: 14.w, height: 14.w),
  279. SizedBox(width: 2.w),
  280. Text(StringName.trackDetailNoAuthorize,
  281. style:
  282. TextStyle(fontSize: 11.sp, color: '#919DBE'.color, height: 1))
  283. ],
  284. );
  285. } else {
  286. return Row(
  287. children: [
  288. Assets.images.iconTrackStay.image(width: 14.w, height: 14.w),
  289. SizedBox(width: 2.w),
  290. if (highUnlock != null && highUnlock == 0)
  291. Text('高频解锁$highUnlock次,共${totalUnlock ?? 0}次',
  292. style:
  293. TextStyle(fontSize: 11.sp, color: '#666666'.color, height: 1))
  294. else
  295. Text('解锁${totalUnlock ?? 0}次',
  296. style:
  297. TextStyle(fontSize: 11.sp, color: '#666666'.color, height: 1))
  298. ],
  299. );
  300. }
  301. }
  302. Widget _buildStayDesc(int duration) {
  303. return Row(
  304. children: [
  305. Assets.images.iconTrackStay.image(width: 14.w, height: 14.w),
  306. SizedBox(width: 2.w),
  307. Text(TrackUtil.formatDurationFromMillis(duration),
  308. style: TextStyle(fontSize: 11.sp, color: '#666666'.color, height: 1))
  309. ],
  310. );
  311. }