track_daily_item.dart 11 KB

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