track_day_detail_view.dart 14 KB

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