track_daily_item.dart 11 KB

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