track_day_detail_view.dart 13 KB

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