track_day_detail_view.dart 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445
  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. Obx(() {
  139. if (controller.trackController.userInfo?.isMine == true) {
  140. return Text(
  141. trackSituation,
  142. style: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  143. );
  144. }
  145. return DropCapText(
  146. style: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  147. trackSituation,
  148. dropCapPosition: DropCapPosition.bottomRight,
  149. textAlign: TextAlign.justify,
  150. dropCap: DropCap(
  151. width: 75.w,
  152. height: 36.w,
  153. child: Align(
  154. alignment: Alignment.bottomRight,
  155. child: GestureDetector(
  156. onTap: controller.onPhoneCallClick,
  157. child: Column(
  158. crossAxisAlignment: CrossAxisAlignment.center,
  159. mainAxisAlignment: MainAxisAlignment.end,
  160. children: [
  161. Assets.images.iconCallPhone
  162. .image(width: 15.w, height: 15.w),
  163. Text(
  164. StringName.trackDailyCallPhone,
  165. style: TextStyle(
  166. fontSize: 10.sp,
  167. color: ColorName.colorPrimary,
  168. fontWeight: FontWeight.bold),
  169. )
  170. ],
  171. ),
  172. ),
  173. )),
  174. );
  175. }),
  176. SizedBox(height: 12.w),
  177. ],
  178. ),
  179. );
  180. }
  181. Widget _buildDailyTrackPrintingView() {
  182. return VisibilityDetector(
  183. key: Key('track-summary-print'),
  184. onVisibilityChanged: (VisibilityInfo info) {
  185. final visibleFraction = info.visibleFraction;
  186. controller.checkGraduallyPrintTextVisible(visibleFraction);
  187. },
  188. child: Container(
  189. width: double.infinity,
  190. padding: EdgeInsets.symmetric(horizontal: 22.w),
  191. child: Column(
  192. crossAxisAlignment: CrossAxisAlignment.start,
  193. children: [
  194. Text(StringName.trackDailySummarytrack,
  195. style: TextStyle(
  196. fontSize: 13.sp,
  197. color: '#333333'.color,
  198. fontWeight: FontWeight.bold)),
  199. SizedBox(height: 8.w),
  200. Obx(() {
  201. if (controller.summaryError?.isNotEmpty == true) {
  202. return Text(controller.summaryError!,
  203. style: TextStyle(fontSize: 11.sp, color: '#FF0000'.color));
  204. } else {
  205. return GraduallyPrintText(
  206. graduallyController: controller.graduallyController,
  207. textStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  208. );
  209. }
  210. }),
  211. SizedBox(height: 12.w),
  212. ],
  213. ),
  214. ),
  215. );
  216. }
  217. Widget buildDailySummaryTitle() {
  218. return Row(
  219. children: [
  220. SizedBox(width: 22.w),
  221. Assets.images.iconTrackDailySummary.image(width: 20.w),
  222. SizedBox(width: 5.w),
  223. Text(StringName.trackDetailDailySummary,
  224. style: TextStyle(
  225. fontWeight: FontWeight.bold,
  226. fontSize: 14.sp,
  227. color: '#333333'.color)),
  228. Spacer(),
  229. GestureDetector(
  230. onTap: controller.onShareClick,
  231. child: Container(
  232. padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 12.w),
  233. child: Row(
  234. children: [
  235. Text(StringName.trackDetailDailySummaryShare,
  236. style: TextStyle(fontSize: 12.sp, color: '#666666'.color)),
  237. Assets.images.iconTrackDailySummaryArrow.image(height: 11.w)
  238. ],
  239. ),
  240. ),
  241. ),
  242. SizedBox(width: 10.w),
  243. ],
  244. );
  245. }
  246. Widget _buildSituationItem(String title, TrackSummary? summary) {
  247. if (summary == null) {
  248. return SizedBox.shrink();
  249. }
  250. return Container(
  251. width: double.infinity,
  252. padding: EdgeInsets.symmetric(horizontal: 22.w),
  253. child: Column(
  254. crossAxisAlignment: CrossAxisAlignment.start,
  255. children: [
  256. Text(title,
  257. style: TextStyle(
  258. fontSize: 13.sp,
  259. color: '#333333'.color,
  260. fontWeight: FontWeight.bold)),
  261. SizedBox(height: 8.w),
  262. RichTextReplace(
  263. text: summary.text,
  264. items: summary.items,
  265. defaultStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color),
  266. replacedStyle: TextStyle(
  267. fontWeight: FontWeight.bold,
  268. fontSize: 11.sp,
  269. color: '#333333'.color)),
  270. SizedBox(height: 12.w),
  271. Container(
  272. width: double.infinity,
  273. height: 1.w,
  274. color: '#EEEEEE'.color,
  275. ),
  276. SizedBox(height: 10.w),
  277. ],
  278. ),
  279. );
  280. }
  281. Widget _buildFoldContentView() {
  282. return Obx(() {
  283. return Column(
  284. crossAxisAlignment: CrossAxisAlignment.start,
  285. children: [
  286. Builder(builder: (context) {
  287. if (controller.expandSituation != null) {
  288. if (controller.expandSituation!.first == TrackExpandType.error ||
  289. controller.expandSituation!.first ==
  290. TrackExpandType.errorNow) {
  291. return buildErrorTrackDailyItem(
  292. controller.expandSituation!.second,
  293. contentPadding: EdgeInsets.only(top: 46.w, bottom: 12.w),
  294. onItemClick: controller.onHistoryTrackItemClick,
  295. onAIAnalyseClick: controller.onAIAnalyseClick);
  296. } else {
  297. return buildStayTrackDailyItem(
  298. controller.expandSituation!.second,
  299. contentPadding: EdgeInsets.only(top: 35.w),
  300. onItemClick: controller.onHistoryTrackItemClick);
  301. }
  302. } else {
  303. return SizedBox.shrink();
  304. }
  305. }),
  306. if (controller.expandSituation != null &&
  307. (controller.expandSituation?.first == TrackExpandType.error ||
  308. controller.expandSituation?.first == TrackExpandType.stay))
  309. buildEndPoint(controller.expandSituation!.second)
  310. ],
  311. );
  312. });
  313. }
  314. Widget _buildTrackNoData() {
  315. return Column(
  316. children: [
  317. SizedBox(height: 0.048.sh),
  318. Assets.images.imgTrackNoData.image(width: 78.5.w),
  319. SizedBox(height: 7.w),
  320. Text(StringName.trackDetailNoData,
  321. style: TextStyle(fontSize: 11.sp, color: ColorName.black60))
  322. ],
  323. );
  324. }
  325. Widget _buildFoldBtn() {
  326. return Obx(() {
  327. return Visibility(
  328. visible: !controller.trackNoData && !controller.isHideExpand,
  329. child: Positioned(
  330. top: 2.w,
  331. right: 5.w,
  332. child: GestureDetector(
  333. behavior: HitTestBehavior.translucent,
  334. onTap: controller.onTrackDetailFoldClick,
  335. child: Container(
  336. padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 8.w),
  337. child: Obx(() {
  338. return Row(
  339. crossAxisAlignment: controller.isExpanded
  340. ? CrossAxisAlignment.end
  341. : CrossAxisAlignment.center,
  342. children: [
  343. Text(
  344. controller.isExpanded
  345. ? StringName.trackDetailFold
  346. : StringName.trackDetailExpand,
  347. style: TextStyle(fontSize: 10.sp, color: '#666666'.color),
  348. ),
  349. SizedBox(width: 1.w),
  350. Transform.rotate(
  351. angle: controller.isExpanded ? 3.1416 : 0,
  352. child: Assets.images.iconTrackDetailTimeBaseArrow
  353. .image(width: 10.w, height: 10.w),
  354. )
  355. ],
  356. );
  357. }),
  358. ),
  359. ),
  360. ),
  361. );
  362. });
  363. }
  364. Widget buildProportionDurationView() {
  365. return Column(
  366. children: [
  367. Container(
  368. width: double.infinity,
  369. height: 293.w,
  370. padding: EdgeInsets.all(12.w),
  371. child: Stack(
  372. children: [
  373. Text(StringName.trackDetailTimeProportion,
  374. style: TextStyle(
  375. fontSize: 13.sp,
  376. color: '#333333'.color,
  377. fontWeight: FontWeight.bold)),
  378. _buildPieChatView()
  379. ],
  380. ),
  381. ),
  382. Container(
  383. height: 8.w,
  384. width: double.infinity,
  385. color: '#F8F5FF'.color,
  386. )
  387. ],
  388. );
  389. }
  390. Widget _buildPieChatView() {
  391. return Obx(() {
  392. if (controller.pieChatData.isEmpty) {
  393. return SizedBox.shrink();
  394. }
  395. return Align(
  396. alignment: Alignment.center,
  397. child: TrackTimePieChat(pieData: controller.pieChatData));
  398. });
  399. }
  400. Widget buildSliverHistoryTrack() {
  401. return Obx(() {
  402. if (controller.isExpanded) {
  403. return SliverPadding(
  404. padding: EdgeInsets.only(top: 20.w, bottom: 12.w),
  405. sliver: SliverList.builder(
  406. itemBuilder: buildHistoryTrackItem,
  407. itemCount: controller.trackDailyList.length),
  408. );
  409. } else {
  410. return SliverPadding(
  411. padding: EdgeInsets.only(
  412. top: 20.w, bottom: 12.w, left: 12.w, right: 12.w),
  413. sliver: SliverToBoxAdapter(
  414. child: _buildFoldContentView(),
  415. ));
  416. }
  417. });
  418. }
  419. Widget buildHistoryTrackItem(BuildContext context, int index) {
  420. return buildTrackDailyItem(controller.trackDailyList[index],
  421. index == controller.trackDailyList.length - 1,
  422. onItemClick: controller.onHistoryTrackItemClick,
  423. onAIAnalyseClick: controller.onAIAnalyseClick);
  424. }
  425. }