track_page.dart 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter/src/widgets/framework.dart';
  4. import 'package:flutter_map/flutter_map.dart';
  5. import 'package:flutter_screenutil/flutter_screenutil.dart';
  6. import 'package:get/get.dart';
  7. import 'package:get/get_core/src/get_main.dart';
  8. import 'package:location/base/base_page.dart';
  9. import 'package:location/data/bean/user_info.dart';
  10. import 'package:location/module/track/track_controller.dart';
  11. import 'package:location/module/track/track_day_detail/track_day_detail_view.dart';
  12. import 'package:location/module/track/track_day_detail/track_share_view.dart';
  13. import 'package:location/resource/colors.gen.dart';
  14. import 'package:location/utils/common_expand.dart';
  15. import 'package:location/utils/common_style.dart';
  16. import 'package:sliding_sheet2/sliding_sheet2.dart';
  17. import '../../resource/assets.gen.dart';
  18. import '../../router/app_pages.dart';
  19. import '../../utils/fixed_size_tab_indicator.dart';
  20. import '../../widget/common_view.dart';
  21. class TrackPage extends BasePage<TrackController> {
  22. const TrackPage({super.key});
  23. static void start(UserInfo userInfo) {
  24. Get.toNamed(RoutePath.track, arguments: userInfo);
  25. }
  26. @override
  27. bool immersive() {
  28. return true;
  29. }
  30. @override
  31. Widget buildBody(BuildContext context) {
  32. return Stack(
  33. children: [
  34. _buildHideShareView(),
  35. SizedBox(
  36. width: double.infinity,
  37. height: double.infinity,
  38. child: MapWidget(
  39. controller: controller.mapController,
  40. ),
  41. ),
  42. buildBackBtnView(),
  43. buildMapFunView(),
  44. SlidingSheet(
  45. listener: (SheetState state) {
  46. controller.setSheetProgress(state.progress);
  47. },
  48. color: ColorName.white,
  49. controller: controller.sheetController,
  50. elevation: 10,
  51. shadowColor: Colors.black.withOpacity(0.1),
  52. cornerRadius: 18.w,
  53. snapSpec: SnapSpec(
  54. initialSnap: 0.45,
  55. // Enable snapping. This is true by default.
  56. snap: true,
  57. // Set custom snapping points.
  58. snappings: [SnapSpec.headerSnap, 0.45, 1.0],
  59. // Define to what the snappings relate to. In this case,
  60. // the total available space that the sheet can expand to.
  61. positioning: SnapPositioning.relativeToAvailableSpace,
  62. ),
  63. headerBuilder: (context, state) {
  64. return buildSheetHeadView();
  65. },
  66. builder: (context, state) {
  67. return buildSheetContentView();
  68. },
  69. ),
  70. ],
  71. );
  72. }
  73. Widget _buildHideShareView() {
  74. return RepaintBoundary(
  75. key: controller.shareGlobalKey,
  76. child: Obx(() {
  77. final day = controller.currentTrackDay.value;
  78. final userInfo = controller.userInfo;
  79. final shareTrackData = controller.shareTrackData;
  80. if (shareTrackData != null && day != null && userInfo != null) {
  81. return TrackShareView(day.start, userInfo, shareTrackData);
  82. }
  83. return SizedBox.shrink();
  84. }),
  85. );
  86. }
  87. Widget buildMapFunView() {
  88. return Obx(() {
  89. return Positioned(
  90. right: 0.w,
  91. bottom: 110.w + controller.sheetProgress * 0.77.sh,
  92. child: Column(
  93. children: [
  94. GestureDetector(
  95. onTap: controller.onCurrentLocationClick,
  96. child: Container(
  97. margin: EdgeInsets.only(right: 12.w),
  98. child: Opacity(
  99. opacity: controller.sheetProgress < 0.6
  100. ? 1.0
  101. : 1.0 -
  102. ((controller.sheetProgress - 0.6) / 0.4)
  103. .clamp(0.0, 1.0),
  104. child: Assets.images.iconMainRefreshMineLocation
  105. .image(width: 42.w, height: 42.w),
  106. )),
  107. ),
  108. ],
  109. ),
  110. );
  111. });
  112. }
  113. Widget buildBackBtnView() {
  114. return SafeArea(
  115. child: GestureDetector(
  116. onTap: controller.back,
  117. child: Container(
  118. margin: EdgeInsets.only(top: 14.w, left: 12.w),
  119. decoration: BoxDecoration(boxShadow: [
  120. BoxShadow(
  121. color: Colors.black.withOpacity(0.05),
  122. blurRadius: 10.w,
  123. offset: Offset(0, 2.w),
  124. ),
  125. ]),
  126. child: CommonView.getBackBtnView(),
  127. ),
  128. ),
  129. );
  130. }
  131. Widget buildSheetContentView() {
  132. return SizedBox(
  133. height: 0.77.sh,
  134. width: double.infinity,
  135. child: Obx(() {
  136. return Visibility(
  137. visible: controller.tabController != null,
  138. child: Column(
  139. children: [
  140. SizedBox(
  141. width: double.infinity,
  142. child: TabBar(
  143. controller: controller.tabController,
  144. tabAlignment: TabAlignment.start,
  145. isScrollable: true,
  146. dividerHeight: 0,
  147. indicator: FixedSizeTabIndicator(
  148. width: 26.w,
  149. height: 3.w,
  150. radius: 0,
  151. color: ColorName.colorPrimary),
  152. unselectedLabelStyle:
  153. TextStyle(fontSize: 13.sp, color: '#666666'.color),
  154. labelStyle: TextStyle(
  155. fontSize: 13.sp,
  156. color: '#333333'.color,
  157. fontWeight: FontWeight.bold),
  158. tabs: controller.daysList.map((e) {
  159. return Tab(
  160. text: e.day,
  161. );
  162. }).toList(),
  163. ),
  164. ),
  165. Container(
  166. color: '#EEEEEE'.color,
  167. height: 1.w,
  168. width: double.infinity,
  169. ),
  170. Expanded(
  171. child: TabBarView(
  172. controller: controller.tabController,
  173. children: List.generate(
  174. controller.daysList.length,
  175. (index) => TrackDayDetailView(controller.daysList[index],
  176. isExpand: index == 0)),
  177. )),
  178. ],
  179. ),
  180. );
  181. }),
  182. );
  183. }
  184. Widget buildSheetHeadView() {
  185. return IntrinsicHeight(
  186. child: Column(
  187. children: [
  188. SizedBox(height: 5.w),
  189. Align(
  190. alignment: Alignment.center,
  191. child: Container(
  192. width: 32.w,
  193. height: 3.w,
  194. decoration: BoxDecoration(
  195. color: '#D9D9D9'.color,
  196. borderRadius: BorderRadius.circular(49.w),
  197. ),
  198. ),
  199. ),
  200. SizedBox(height: 25.w),
  201. buildTrackHeaderView(),
  202. SizedBox(height: 20.w),
  203. ],
  204. ));
  205. }
  206. Widget buildTrackHeaderView() {
  207. return Row(
  208. children: [
  209. SizedBox(width: 14.w),
  210. Obx(() {
  211. return buildCustomAvatarOrDefaultAvatarView(
  212. size: 32.w,
  213. avatar: controller.userInfo?.avatar,
  214. isMine: controller.userInfo?.isMine == true);
  215. }),
  216. SizedBox(width: 10.w),
  217. Expanded(
  218. child: Text(
  219. '${controller.userInfo?.getUserNickName() ?? ''}的轨迹',
  220. style: TextStyle(
  221. overflow: TextOverflow.ellipsis,
  222. fontSize: 16.sp,
  223. color: ColorName.black80,
  224. fontWeight: FontWeight.bold),
  225. ),
  226. ),
  227. SizedBox(width: 12.w),
  228. ],
  229. );
  230. }
  231. }