import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:location/base/base_view.dart'; import 'package:location/data/bean/track_days.dart'; import 'package:location/module/track/track_day_detail/time_proportion/track_time_pie_chat.dart'; import 'package:location/module/track/track_day_detail/track_daily_item.dart'; import 'package:location/module/track/track_day_detail/track_day_detail_controller.dart'; import 'package:location/module/track/track_status.dart'; import 'package:location/resource/assets.gen.dart'; import 'package:location/resource/colors.gen.dart'; import 'package:location/resource/string.gen.dart'; import 'package:location/utils/atmob_log.dart'; import 'package:location/utils/common_expand.dart'; import 'package:location/utils/toast_util.dart'; import 'package:location/widget/rich_text_replace.dart'; import 'package:visibility_detector/visibility_detector.dart'; import '../../../data/bean/track_summary.dart'; import '../../../widget/drop_cap_text.dart'; import '../../../widget/gradually_print_text.dart'; class TrackDayDetailView extends BaseView { late final String trackTag; TrackDayDetailView(TrackDays days, {super.key, bool isExpand = false}) { trackTag = 'TrackDayDetailView_${days.day}'; Get.lazyPut(() => TrackDayDetailController(days, isExpand), tag: trackTag, fenix: true); } @override TrackDayDetailController get controller => Get.find(tag: trackTag); @override Widget buildBody(BuildContext context) { return Obx(() { return Visibility( visible: controller.isRequested, child: _buildTrackDetailView(), ); }); } Widget _buildTrackDetailView() { return Obx(() { if (controller.trackNoData) { return _buildTrackNoData(); } return _buildTrackListView(); }); } Widget _buildTrackListView() { return Stack( children: [ CustomScrollView( slivers: [ buildSliverHistoryTrack(), SliverToBoxAdapter( child: Container( height: 8.w, color: '#F8F5FF'.color, )), SliverToBoxAdapter( child: buildProportionDurationView(), ), SliverToBoxAdapter( child: buildTrackDailySummaryView(), ), SliverToBoxAdapter( child: buildTrackExtraBottomView(), ), SliverToBoxAdapter( child: Container( height: 80.w, color: '#F8F5FF'.color, )), ], ), _buildFoldBtn(), ], ); } Widget buildTrackExtraBottomView() { return Obx(() { return Container( height: controller.trackBottomHeight, color: '#F8F5FF'.color, ); }); } Widget buildTrackDailySummaryView() { return RepaintBoundary( key: controller.shareGlobalKey, child: Column( children: [ buildDailySummaryTitle(), SizedBox(height: 8.w), Obx(() { return _buildSituationItem(StringName.trackDailySummaryPhone, controller.trackDailySummary?.phoneSituation); }), Obx(() { return _buildSituationItem(StringName.trackDailySummaryStay, controller.trackDailySummary?.stayLongest); }), //轨迹情况 Obx(() { return _buildDailyTrack( controller.trackDailySummary?.showTrackSituation, controller.trackDailySummary?.trackSituation); }), SizedBox(height: 10.w) ], ), ); } Widget _buildDailyTrack(bool? isShow, String? trackSituation) { if (isShow == false) { return SizedBox.shrink(); } if (trackSituation != null && trackSituation.isNotEmpty) { return _buildDailyDoneSituationView(trackSituation); } return _buildDailyTrackPrintingView(); } Widget _buildDailyDoneSituationView(String trackSituation) { return Container( width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 22.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(StringName.trackDailySummarytrack, style: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold)), SizedBox(height: 8.w), DropCapText( style: TextStyle(fontSize: 11.sp, color: '#666666'.color), trackSituation, dropCapPosition: DropCapPosition.bottomRight, textAlign: TextAlign.justify, dropCap: DropCap( width: 75.w, height: 36.w, child: Align( alignment: Alignment.bottomRight, child: GestureDetector( onTap: controller.onPhoneCallClick, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.end, children: [ Assets.images.iconCallPhone .image(width: 15.w, height: 15.w), Text( StringName.trackDailyCallPhone, style: TextStyle( fontSize: 10.sp, color: ColorName.colorPrimary, fontWeight: FontWeight.bold), ) ], ), ), )), ), SizedBox(height: 12.w), ], ), ); } Widget _buildDailyTrackPrintingView() { return VisibilityDetector( key: Key('track-summary-print'), onVisibilityChanged: (VisibilityInfo info) { final visibleFraction = info.visibleFraction; controller.checkGraduallyPrintTextVisible(visibleFraction); }, child: Container( width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 22.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(StringName.trackDailySummarytrack, style: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold)), SizedBox(height: 8.w), Obx(() { if (controller.summaryError?.isNotEmpty == true) { return Text(controller.summaryError!, style: TextStyle(fontSize: 11.sp, color: '#FF0000'.color)); } else { return GraduallyPrintText( graduallyController: controller.graduallyController, textStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color), ); } }), SizedBox(height: 12.w), ], ), ), ); } Widget buildDailySummaryTitle() { return Row( children: [ SizedBox(width: 22.w), Assets.images.iconTrackDailySummary.image(width: 20.w), SizedBox(width: 5.w), Text(StringName.trackDetailDailySummary, style: TextStyle( fontWeight: FontWeight.bold, fontSize: 14.sp, color: '#333333'.color)), Spacer(), GestureDetector( onTap: controller.onShareClick, child: Container( padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 12.w), child: Row( children: [ Text(StringName.trackDetailDailySummaryShare, style: TextStyle(fontSize: 12.sp, color: '#666666'.color)), Assets.images.iconTrackDailySummaryArrow.image(height: 11.w) ], ), ), ), SizedBox(width: 10.w), ], ); } Widget _buildSituationItem(String title, TrackSummary? summary) { if (summary == null) { return SizedBox.shrink(); } return Container( width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 22.w), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold)), SizedBox(height: 8.w), RichTextReplace( text: summary.text, items: summary.items, defaultStyle: TextStyle(fontSize: 11.sp, color: '#666666'.color), replacedStyle: TextStyle( fontWeight: FontWeight.bold, fontSize: 11.sp, color: '#333333'.color)), SizedBox(height: 12.w), Container( width: double.infinity, height: 1.w, color: '#EEEEEE'.color, ), SizedBox(height: 10.w), ], ), ); } Widget _buildFoldContentView() { return Obx(() { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Builder(builder: (context) { if (controller.expandSituation != null) { if (controller.expandSituation!.first == TrackExpandType.error || controller.expandSituation!.first == TrackExpandType.errorNow) { return buildErrorTrackDailyItem( controller.expandSituation!.second, contentPadding: EdgeInsets.only(top: 46.w, bottom: 12.w), onItemClick: controller.onHistoryTrackItemClick, onAIAnalyseClick: controller.onAIAnalyseClick); } else { return buildStayTrackDailyItem( controller.expandSituation!.second, contentPadding: EdgeInsets.only(top: 35.w), onItemClick: controller.onHistoryTrackItemClick); } } else { return SizedBox.shrink(); } }), if (controller.expandSituation != null && (controller.expandSituation?.first == TrackExpandType.error || controller.expandSituation?.first == TrackExpandType.stay)) buildEndPoint(controller.expandSituation!.second) ], ); }); } Widget _buildTrackNoData() { return Column( children: [ SizedBox(height: 0.048.sh), Assets.images.imgTrackNoData.image(width: 78.5.w), SizedBox(height: 7.w), Text(StringName.trackDetailNoData, style: TextStyle(fontSize: 11.sp, color: ColorName.black60)) ], ); } Widget _buildFoldBtn() { return Obx(() { return Visibility( visible: !controller.trackNoData && !controller.isHideExpand, child: Positioned( top: 2.w, right: 5.w, child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: controller.onTrackDetailFoldClick, child: Container( padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 8.w), child: Obx(() { return Row( crossAxisAlignment: controller.isExpanded ? CrossAxisAlignment.end : CrossAxisAlignment.center, children: [ Text( controller.isExpanded ? StringName.trackDetailFold : StringName.trackDetailExpand, style: TextStyle(fontSize: 10.sp, color: '#666666'.color), ), SizedBox(width: 1.w), Transform.rotate( angle: controller.isExpanded ? 3.1416 : 0, child: Assets.images.iconTrackDetailTimeBaseArrow .image(width: 10.w, height: 10.w), ) ], ); }), ), ), ), ); }); } Widget buildProportionDurationView() { return Column( children: [ Container( width: double.infinity, height: 293.w, padding: EdgeInsets.all(12.w), child: Stack( children: [ Text(StringName.trackDetailTimeProportion, style: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold)), _buildPieChatView() ], ), ), Container( height: 8.w, width: double.infinity, color: '#F8F5FF'.color, ) ], ); } Widget _buildPieChatView() { return Obx(() { if (controller.pieChatData.isEmpty) { return SizedBox.shrink(); } return Align( alignment: Alignment.center, child: TrackTimePieChat(pieData: controller.pieChatData)); }); } Widget buildSliverHistoryTrack() { return Obx(() { if (controller.isExpanded) { return SliverPadding( padding: EdgeInsets.only(top: 20.w, bottom: 12.w), sliver: SliverList.builder( itemBuilder: buildHistoryTrackItem, itemCount: controller.trackDailyList.length), ); } else { return SliverPadding( padding: EdgeInsets.only( top: 20.w, bottom: 12.w, left: 12.w, right: 12.w), sliver: SliverToBoxAdapter( child: _buildFoldContentView(), )); } }); } Widget buildHistoryTrackItem(BuildContext context, int index) { return buildTrackDailyItem(controller.trackDailyList[index], index == controller.trackDailyList.length - 1, onItemClick: controller.onHistoryTrackItemClick, onAIAnalyseClick: controller.onAIAnalyseClick); } }