import 'dart:io'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_map/flutter_map.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_page.dart'; import 'package:location/data/bean/user_info.dart'; import 'package:location/module/track/track_controller.dart'; import 'package:location/module/track/track_day_detail/track_day_detail_view.dart'; import 'package:location/module/track/track_day_detail/track_share_view.dart'; import 'package:location/resource/colors.gen.dart'; import 'package:location/utils/common_expand.dart'; import 'package:location/utils/common_style.dart'; import 'package:sliding_sheet2/sliding_sheet2.dart'; import '../../resource/assets.gen.dart'; import '../../resource/string.gen.dart'; import '../../router/app_pages.dart'; import '../../utils/fixed_size_tab_indicator.dart'; import '../../widget/common_view.dart'; class TrackPage extends BasePage { const TrackPage({super.key}); static void start(UserInfo userInfo) { Get.toNamed(RoutePath.track, arguments: userInfo); } @override bool immersive() { return true; } @override Widget buildBody(BuildContext context) { return Stack( children: [ _buildHideShareView(), SizedBox( width: double.infinity, height: double.infinity, child: MapWidget( controller: controller.mapController, ), ), buildBackBtnView(), buildMapFunView(), SlidingSheet( listener: (SheetState state) { controller.setSheetProgress(state.progress); }, color: ColorName.white, controller: controller.sheetController, elevation: 10, shadowColor: Colors.black.withOpacity(0.1), cornerRadius: 18.w, snapSpec: SnapSpec( initialSnap: 0.45, // Enable snapping. This is true by default. snap: true, // Set custom snapping points. snappings: [SnapSpec.headerSnap, 0.45, 1.0], // Define to what the snappings relate to. In this case, // the total available space that the sheet can expand to. positioning: SnapPositioning.relativeToAvailableSpace, ), headerBuilder: (context, state) { return buildSheetHeadView(); }, builder: (context, state) { return buildSheetContentView(); }, ), Visibility( visible: Platform.isAndroid, child: SafeArea( child: Container( width: double.infinity, padding: EdgeInsets.only(right: 12.w), child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Assets.images.iconAmapLogo.image(height: 24.w), Container( padding: EdgeInsets.all(1.w), color: ColorName.white30, child: Text(StringName.locationCo, style: TextStyle( fontSize: 11.sp, color: ColorName.black40)), ) ], ), ), ), ), ], ); } Widget _buildHideShareView() { return RepaintBoundary( key: controller.shareGlobalKey, child: Obx(() { final day = controller.currentTrackDay.value; final userInfo = controller.userInfo; final shareTrackData = controller.shareTrackData; if (shareTrackData != null && day != null && userInfo != null) { return TrackShareView(day.start, userInfo, shareTrackData); } return SizedBox.shrink(); }), ); } Widget buildMapFunView() { return Obx(() { return Positioned( right: 0.w, bottom: 110.w + controller.sheetProgress * 0.77.sh, child: Column( children: [ GestureDetector( onTap: controller.onCurrentLocationClick, child: Container( margin: EdgeInsets.only(right: 12.w), child: Opacity( opacity: controller.sheetProgress < 0.6 ? 1.0 : 1.0 - ((controller.sheetProgress - 0.6) / 0.4) .clamp(0.0, 1.0), child: Assets.images.iconMainRefreshMineLocation .image(width: 42.w, height: 42.w), )), ), ], ), ); }); } Widget buildBackBtnView() { return SafeArea( child: GestureDetector( onTap: controller.back, child: Container( margin: EdgeInsets.only(top: 14.w, left: 12.w), decoration: BoxDecoration(boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 10.w, offset: Offset(0, 2.w), ), ]), child: CommonView.getBackBtnView(), ), ), ); } Widget buildSheetContentView() { return SizedBox( height: 0.77.sh, width: double.infinity, child: Obx(() { return Visibility( visible: controller.tabController != null, child: Column( children: [ SizedBox( width: double.infinity, child: TabBar( controller: controller.tabController, tabAlignment: TabAlignment.start, isScrollable: true, dividerHeight: 0, indicator: FixedSizeTabIndicator( width: 26.w, height: 3.w, radius: 0, color: ColorName.colorPrimary), unselectedLabelStyle: TextStyle(fontSize: 13.sp, color: '#666666'.color), labelStyle: TextStyle( fontSize: 13.sp, color: '#333333'.color, fontWeight: FontWeight.bold), tabs: controller.daysList.map((e) { return Tab( text: e.day, ); }).toList(), ), ), Container( color: '#EEEEEE'.color, height: 1.w, width: double.infinity, ), Expanded( child: TabBarView( controller: controller.tabController, children: List.generate( controller.daysList.length, (index) => TrackDayDetailView(controller.daysList[index], isExpand: index == 0)), )), ], ), ); }), ); } Widget buildSheetHeadView() { return IntrinsicHeight( child: Column( children: [ SizedBox(height: 5.w), Align( alignment: Alignment.center, child: Container( width: 32.w, height: 3.w, decoration: BoxDecoration( color: '#D9D9D9'.color, borderRadius: BorderRadius.circular(49.w), ), ), ), SizedBox(height: 25.w), buildTrackHeaderView(), SizedBox(height: 20.w), ], )); } Widget buildTrackHeaderView() { return Row( children: [ SizedBox(width: 14.w), Obx(() { return buildCustomAvatarOrDefaultAvatarView( size: 32.w, avatar: controller.userInfo?.avatar, isMine: controller.userInfo?.isMine == true); }), SizedBox(width: 10.w), Expanded( child: Text( '${controller.userInfo?.getUserNickName() ?? ''}的轨迹', style: TextStyle( overflow: TextOverflow.ellipsis, fontSize: 16.sp, color: ColorName.black80, fontWeight: FontWeight.bold), ), ), SizedBox(width: 12.w), ], ); } }