track_day_detail_view.dart 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/src/widgets/framework.dart';
  4. import 'package:flutter_screenutil/flutter_screenutil.dart';
  5. import 'package:get/get.dart';
  6. import 'package:get/get_core/src/get_main.dart';
  7. import 'package:location/base/base_view.dart';
  8. import 'package:location/data/bean/track_days.dart';
  9. import 'package:location/module/track/track_day_detail/time_proportion/track_time_pie_chat.dart';
  10. import 'package:location/module/track/track_day_detail/track_daily_item.dart';
  11. import 'package:location/module/track/track_day_detail/track_day_detail_controller.dart';
  12. import 'package:location/module/track/track_status.dart';
  13. import 'package:location/resource/assets.gen.dart';
  14. import 'package:location/resource/colors.gen.dart';
  15. import 'package:location/resource/string.gen.dart';
  16. import 'package:location/utils/atmob_log.dart';
  17. import 'package:location/utils/common_expand.dart';
  18. import 'package:location/utils/toast_util.dart';
  19. import 'package:location/widget/rich_text_replace.dart';
  20. import 'package:visibility_detector/visibility_detector.dart';
  21. import '../../../data/bean/track_summary.dart';
  22. import '../../../widget/drop_cap_text.dart';
  23. import '../../../widget/gradually_print_text.dart';
  24. class TrackDayDetailView extends BaseView<TrackDayDetailController> {
  25. late final String trackTag;
  26. TrackDayDetailView(TrackDays days, {super.key, bool isExpand = false}) {
  27. trackTag = 'TrackDayDetailView_${days.day}';
  28. Get.lazyPut(() => TrackDayDetailController(days, isExpand),
  29. tag: trackTag, fenix: true);
  30. }
  31. @override
  32. TrackDayDetailController get controller =>
  33. Get.find<TrackDayDetailController>(tag: trackTag);
  34. @override
  35. Widget buildBody(BuildContext context) {
  36. return Obx(() {
  37. return Visibility(
  38. visible: controller.isRequested,
  39. child: _buildTrackDetailView(),
  40. );
  41. });
  42. }
  43. Widget _buildTrackDetailView() {
  44. return Obx(() {
  45. if (controller.trackNoData) {
  46. return _buildTrackNoData();
  47. }
  48. return _buildTrackListView();
  49. });
  50. }
  51. Widget _buildTrackListView() {
  52. return Stack(
  53. children: [
  54. CustomScrollView(
  55. slivers: [
  56. buildSliverHistoryTrack(),
  57. SliverToBoxAdapter(
  58. child: Container(
  59. height: 8.w,
  60. color: '#F8F5FF'.color,
  61. )),
  62. SliverToBoxAdapter(
  63. child: buildProportionDurationView(),
  64. ),
  65. SliverToBoxAdapter(
  66. child: buildTrackDailySummaryView(),
  67. ),
  68. SliverToBoxAdapter(
  69. child: buildTrackExtraBottomView(),
  70. ),
  71. SliverToBoxAdapter(
  72. child: Container(
  73. height: 80.w,
  74. color: '#F8F5FF'.color,
  75. )),
  76. ],
  77. ),
  78. _buildFoldBtn(),
  79. ],
  80. );
  81. }
  82. Widget buildTrackExtraBottomView() {
  83. return Obx(() {
  84. return Container(
  85. height: controller.trackBottomHeight,
  86. color: '#F8F5FF'.color,
  87. );
  88. });
  89. }
  90. Widget buildTrackDailySummaryView() {
  91. return RepaintBoundary(
  92. key: controller.shareGlobalKey,
  93. child: Column(
  94. children: [
  95. buildDailySummaryTitle(),
  96. SizedBox(height: 8.w),
  97. Obx(() {
  98. return _buildSituationItem(StringName.trackDailySummaryPhone,
  99. controller.trackDailySummary?.phoneSituation);
  100. }),
  101. Obx(() {
  102. return _buildSituationItem(StringName.trackDailySummaryStay,
  103. controller.trackDailySummary?.stayLongest);
  104. }),
  105. //轨迹情况
  106. Obx(() {
  107. return _buildDailyTrack(
  108. controller.trackDailySummary?.showTrackSituation,
  109. controller.trackDailySummary?.trackSituation);
  110. }),
  111. SizedBox(height: 10.w)
  112. ],
  113. ),
  114. );
  115. }
  116. Widget _buildDailyTrack(bool? isShow, String? trackSituation) {
  117. if (isShow == false) {
  118. return SizedBox.shrink();
  119. }
  120. if (trackSituation != null && trackSituation.isNotEmpty) {
  121. return _buildDailyDoneSituationView(trackSituation);
  122. }
  123. return _buildDailyTrackPrintingView();
  124. }
  125. Widget _buildDailyDoneSituationView(String trackSituation) {
  126. return Container(
  127. width: double.infinity,
  128. padding: EdgeInsets.symmetric(horizontal: 22.w),
  129. child: Column(
  130. crossAxisAlignment: CrossAxisAlignment.start,
  131. children: [
  132. Text(StringName.trackDailySummarytrack,
  133. style: TextStyle(
  134. fontSize: 13.sp,
  135. color: '#333333'.color,
  136. fontWeight: FontWeight.bold)),
  137. SizedBox(height: 8.w),
  138. DropCapText(
  139. style: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  140. trackSituation,
  141. dropCapPosition: DropCapPosition.bottomRight,
  142. textAlign: TextAlign.justify,
  143. dropCap: DropCap(
  144. width: 75.w,
  145. height: 36.w,
  146. child: Align(
  147. alignment: Alignment.bottomRight,
  148. child: GestureDetector(
  149. onTap: controller.onPhoneCallClick,
  150. child: Column(
  151. crossAxisAlignment: CrossAxisAlignment.center,
  152. mainAxisAlignment: MainAxisAlignment.end,
  153. children: [
  154. Assets.images.iconCallPhone
  155. .image(width: 15.w, height: 15.w),
  156. Text(
  157. StringName.trackDailyCallPhone,
  158. style: TextStyle(
  159. fontSize: 10.sp,
  160. color: ColorName.colorPrimary,
  161. fontWeight: FontWeight.bold),
  162. )
  163. ],
  164. ),
  165. ),
  166. )),
  167. ),
  168. SizedBox(height: 12.w),
  169. ],
  170. ),
  171. );
  172. }
  173. Widget _buildDailyTrackPrintingView() {
  174. return VisibilityDetector(
  175. key: Key('track-summary-print'),
  176. onVisibilityChanged: (VisibilityInfo info) {
  177. final visibleFraction = info.visibleFraction;
  178. controller.checkGraduallyPrintTextVisible(visibleFraction);
  179. },
  180. child: Container(
  181. width: double.infinity,
  182. padding: EdgeInsets.symmetric(horizontal: 22.w),
  183. child: Column(
  184. crossAxisAlignment: CrossAxisAlignment.start,
  185. children: [
  186. Text(StringName.trackDailySummarytrack,
  187. style: TextStyle(
  188. fontSize: 13.sp,
  189. color: '#333333'.color,
  190. fontWeight: FontWeight.bold)),
  191. SizedBox(height: 8.w),
  192. Obx(() {
  193. if (controller.summaryError?.isNotEmpty == true) {
  194. return Text(controller.summaryError!,
  195. style: TextStyle(fontSize: 11.sp, color: '#FF0000'.color));
  196. } else {
  197. return GraduallyPrintText(
  198. graduallyController: controller.graduallyController,
  199. textStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  200. );
  201. }
  202. }),
  203. SizedBox(height: 12.w),
  204. ],
  205. ),
  206. ),
  207. );
  208. }
  209. Widget buildDailySummaryTitle() {
  210. return Row(
  211. children: [
  212. SizedBox(width: 22.w),
  213. Assets.images.iconTrackDailySummary.image(width: 20.w),
  214. SizedBox(width: 5.w),
  215. Text(StringName.trackDetailDailySummary,
  216. style: TextStyle(
  217. fontWeight: FontWeight.bold,
  218. fontSize: 14.sp,
  219. color: '#333333'.color)),
  220. Spacer(),
  221. GestureDetector(
  222. onTap: controller.onShareClick,
  223. child: Container(
  224. padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 12.w),
  225. child: Row(
  226. children: [
  227. Text(StringName.trackDetailDailySummaryShare,
  228. style: TextStyle(fontSize: 12.sp, color: '#666666'.color)),
  229. Assets.images.iconTrackDailySummaryArrow.image(height: 11.w)
  230. ],
  231. ),
  232. ),
  233. ),
  234. SizedBox(width: 10.w),
  235. ],
  236. );
  237. }
  238. Widget _buildSituationItem(String title, TrackSummary? summary) {
  239. if (summary == null) {
  240. return SizedBox.shrink();
  241. }
  242. return Container(
  243. width: double.infinity,
  244. padding: EdgeInsets.symmetric(horizontal: 22.w),
  245. child: Column(
  246. crossAxisAlignment: CrossAxisAlignment.start,
  247. children: [
  248. Text(title,
  249. style: TextStyle(
  250. fontSize: 13.sp,
  251. color: '#333333'.color,
  252. fontWeight: FontWeight.bold)),
  253. SizedBox(height: 8.w),
  254. RichTextReplace(
  255. text: summary.text,
  256. items: summary.items,
  257. defaultStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  258. replacedStyle: TextStyle(
  259. fontWeight: FontWeight.bold,
  260. fontSize: 11.sp,
  261. color: '#333333'.color)),
  262. SizedBox(height: 12.w),
  263. Container(
  264. width: double.infinity,
  265. height: 1.w,
  266. color: '#EEEEEE'.color,
  267. ),
  268. SizedBox(height: 10.w),
  269. ],
  270. ),
  271. );
  272. }
  273. Widget _buildFoldContentView() {
  274. return Obx(() {
  275. return Column(
  276. crossAxisAlignment: CrossAxisAlignment.start,
  277. children: [
  278. Builder(builder: (context) {
  279. if (controller.expandSituation != null) {
  280. if (controller.expandSituation!.first == TrackExpandType.error ||
  281. controller.expandSituation!.first ==
  282. TrackExpandType.errorNow) {
  283. return buildErrorTrackDailyItem(
  284. controller.expandSituation!.second,
  285. contentPadding: EdgeInsets.only(top: 46.w, bottom: 12.w),
  286. onItemClick: controller.onHistoryTrackItemClick,
  287. onAIAnalyseClick: controller.onAIAnalyseClick);
  288. } else {
  289. return buildStayTrackDailyItem(
  290. controller.expandSituation!.second,
  291. contentPadding: EdgeInsets.only(top: 35.w),
  292. onItemClick: controller.onHistoryTrackItemClick);
  293. }
  294. } else {
  295. return SizedBox.shrink();
  296. }
  297. }),
  298. if (controller.expandSituation != null &&
  299. (controller.expandSituation?.first == TrackExpandType.error ||
  300. controller.expandSituation?.first == TrackExpandType.stay))
  301. buildEndPoint(controller.expandSituation!.second)
  302. ],
  303. );
  304. });
  305. }
  306. Widget _buildTrackNoData() {
  307. return Column(
  308. children: [
  309. SizedBox(height: 0.048.sh),
  310. Assets.images.imgTrackNoData.image(width: 78.5.w),
  311. SizedBox(height: 7.w),
  312. Text(StringName.trackDetailNoData,
  313. style: TextStyle(fontSize: 11.sp, color: ColorName.black60))
  314. ],
  315. );
  316. }
  317. Widget _buildFoldBtn() {
  318. return Obx(() {
  319. return Visibility(
  320. visible: !controller.trackNoData && !controller.isHideExpand,
  321. child: Positioned(
  322. top: 2.w,
  323. right: 5.w,
  324. child: GestureDetector(
  325. behavior: HitTestBehavior.translucent,
  326. onTap: controller.onTrackDetailFoldClick,
  327. child: Container(
  328. padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 8.w),
  329. child: Obx(() {
  330. return Row(
  331. crossAxisAlignment: controller.isExpanded
  332. ? CrossAxisAlignment.end
  333. : CrossAxisAlignment.center,
  334. children: [
  335. Text(
  336. controller.isExpanded
  337. ? StringName.trackDetailFold
  338. : StringName.trackDetailExpand,
  339. style: TextStyle(fontSize: 10.sp, color: '#666666'.color),
  340. ),
  341. SizedBox(width: 1.w),
  342. Transform.rotate(
  343. angle: controller.isExpanded ? 3.1416 : 0,
  344. child: Assets.images.iconTrackDetailTimeBaseArrow
  345. .image(width: 10.w, height: 10.w),
  346. )
  347. ],
  348. );
  349. }),
  350. ),
  351. ),
  352. ),
  353. );
  354. });
  355. }
  356. Widget buildProportionDurationView() {
  357. return Column(
  358. children: [
  359. Container(
  360. width: double.infinity,
  361. height: 293.w,
  362. padding: EdgeInsets.all(12.w),
  363. child: Stack(
  364. children: [
  365. Text(StringName.trackDetailTimeProportion,
  366. style: TextStyle(
  367. fontSize: 13.sp,
  368. color: '#333333'.color,
  369. fontWeight: FontWeight.bold)),
  370. _buildPieChatView()
  371. ],
  372. ),
  373. ),
  374. Container(
  375. height: 8.w,
  376. width: double.infinity,
  377. color: '#F8F5FF'.color,
  378. )
  379. ],
  380. );
  381. }
  382. Widget _buildPieChatView() {
  383. return Obx(() {
  384. if (controller.pieChatData.isEmpty) {
  385. return SizedBox.shrink();
  386. }
  387. return Align(
  388. alignment: Alignment.center,
  389. child: TrackTimePieChat(pieData: controller.pieChatData));
  390. });
  391. }
  392. Widget buildSliverHistoryTrack() {
  393. return Obx(() {
  394. if (controller.isExpanded) {
  395. return SliverPadding(
  396. padding: EdgeInsets.only(top: 20.w, bottom: 12.w),
  397. sliver: SliverList.builder(
  398. itemBuilder: buildHistoryTrackItem,
  399. itemCount: controller.trackDailyList.length),
  400. );
  401. } else {
  402. return SliverPadding(
  403. padding: EdgeInsets.only(
  404. top: 20.w, bottom: 12.w, left: 12.w, right: 12.w),
  405. sliver: SliverToBoxAdapter(
  406. child: _buildFoldContentView(),
  407. ));
  408. }
  409. });
  410. }
  411. Widget buildHistoryTrackItem(BuildContext context, int index) {
  412. return buildTrackDailyItem(controller.trackDailyList[index],
  413. index == controller.trackDailyList.length - 1,
  414. onItemClick: controller.onHistoryTrackItemClick,
  415. onAIAnalyseClick: controller.onAIAnalyseClick);
  416. }
  417. }