|
@@ -1,21 +1,30 @@
|
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
|
+import 'package:flutter/material.dart';
|
|
|
import 'package:flutter/src/widgets/framework.dart';
|
|
import 'package:flutter/src/widgets/framework.dart';
|
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
import 'package:flutter_map/flutter_map.dart';
|
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
import 'package:get/get.dart';
|
|
import 'package:get/get.dart';
|
|
|
import 'package:get/get_core/src/get_main.dart';
|
|
import 'package:get/get_core/src/get_main.dart';
|
|
|
import 'package:location/base/base_page.dart';
|
|
import 'package:location/base/base_page.dart';
|
|
|
-import 'package:location/dialog/agreement_dialog.dart';
|
|
|
|
|
|
|
+import 'package:location/data/bean/user_info.dart';
|
|
|
import 'package:location/module/track/track_controller.dart';
|
|
import 'package:location/module/track/track_controller.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/common_expand.dart';
|
|
|
|
|
+import 'package:location/utils/common_style.dart';
|
|
|
|
|
+import 'package:location/utils/date_util.dart';
|
|
|
|
|
+import 'package:sliding_sheet2/sliding_sheet2.dart';
|
|
|
|
|
|
|
|
import '../../router/app_pages.dart';
|
|
import '../../router/app_pages.dart';
|
|
|
import '../../widget/common_view.dart';
|
|
import '../../widget/common_view.dart';
|
|
|
|
|
+import '../../widget/relative_time_text.dart';
|
|
|
|
|
|
|
|
class TrackPage extends BasePage<TrackController> {
|
|
class TrackPage extends BasePage<TrackController> {
|
|
|
const TrackPage({super.key});
|
|
const TrackPage({super.key});
|
|
|
|
|
|
|
|
- static void start() {
|
|
|
|
|
- Get.toNamed(RoutePath.track);
|
|
|
|
|
|
|
+ static void start(UserInfo userInfo) {
|
|
|
|
|
+ Get.toNamed(RoutePath.track, arguments: userInfo);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
@override
|
|
@@ -41,6 +50,313 @@ class TrackPage extends BasePage<TrackController> {
|
|
|
onTap: controller.back, child: CommonView.getBackBtnView()),
|
|
onTap: controller.back, child: CommonView.getBackBtnView()),
|
|
|
),
|
|
),
|
|
|
),
|
|
),
|
|
|
|
|
+ SlidingSheet(
|
|
|
|
|
+ controller: controller.sheetController,
|
|
|
|
|
+ elevation: 10,
|
|
|
|
|
+ shadowColor: Colors.black.withOpacity(0.1),
|
|
|
|
|
+ cornerRadius: 18.w,
|
|
|
|
|
+ snapSpec: SnapSpec(
|
|
|
|
|
+ initialSnap: 1,
|
|
|
|
|
+ // Enable snapping. This is true by default.
|
|
|
|
|
+ snap: true,
|
|
|
|
|
+ // Set custom snapping points.
|
|
|
|
|
+ snappings: [168 / Get.height, 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,
|
|
|
|
|
+ ),
|
|
|
|
|
+ footerBuilder: (context, state) {
|
|
|
|
|
+ return buildOperationBtn();
|
|
|
|
|
+ },
|
|
|
|
|
+ builder: (context, state) {
|
|
|
|
|
+ return 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(
|
|
|
|
|
+ width: double.infinity,
|
|
|
|
|
+ height: 220.w,
|
|
|
|
|
+ child: TabBarView(
|
|
|
|
|
+ controller: controller.tabController,
|
|
|
|
|
+ children: [
|
|
|
|
|
+ buildTrackHistoryContentView(),
|
|
|
|
|
+ buildTrackNowContentView()
|
|
|
|
|
+ ]),
|
|
|
|
|
+ )
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+ },
|
|
|
|
|
+ )
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildOperationBtn() {
|
|
|
|
|
+ return GestureDetector(
|
|
|
|
|
+ onTap: controller.onTrackQueryClick,
|
|
|
|
|
+ child: Container(
|
|
|
|
|
+ width: 322.w,
|
|
|
|
|
+ height: 46.w,
|
|
|
|
|
+ margin: EdgeInsets.only(bottom: 18.w, top: 9.w),
|
|
|
|
|
+ decoration: getPrimaryBtnDecoration(46.w),
|
|
|
|
|
+ child: Center(
|
|
|
|
|
+ child: Obx(() {
|
|
|
|
|
+ return Text(
|
|
|
|
|
+ controller.currentIndex == 0
|
|
|
|
|
+ ? StringName.trackQueryPath
|
|
|
|
|
+ : StringName.trackNowLocation,
|
|
|
|
|
+ style: TextStyle(fontSize: 14.sp, color: Colors.white),
|
|
|
|
|
+ );
|
|
|
|
|
+ }),
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildTrackHeaderView() {
|
|
|
|
|
+ return Row(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(width: 14.w),
|
|
|
|
|
+ Obx(() {
|
|
|
|
|
+ return Image(
|
|
|
|
|
+ image: controller.userInfo?.isMine == true
|
|
|
|
|
+ ? Assets.images.iconDefaultMineAvatar.provider()
|
|
|
|
|
+ : Assets.images.iconDefaultFriendAvatar.provider(),
|
|
|
|
|
+ width: 32.w,
|
|
|
|
|
+ height: 32.w);
|
|
|
|
|
+ }),
|
|
|
|
|
+ SizedBox(width: 10.w),
|
|
|
|
|
+ Expanded(
|
|
|
|
|
+ child: Text(
|
|
|
|
|
+ '${controller.userInfo?.getUserNickName() ?? ''}的轨迹',
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ overflow: TextOverflow.ellipsis,
|
|
|
|
|
+ fontSize: 16.sp,
|
|
|
|
|
+ color: ColorName.black80,
|
|
|
|
|
+ fontWeight: FontWeight.bold),
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ buildOperationTabBar(),
|
|
|
|
|
+ SizedBox(width: 12.w),
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildOperationTabBar() {
|
|
|
|
|
+ return IntrinsicWidth(
|
|
|
|
|
+ child: Container(
|
|
|
|
|
+ padding: EdgeInsets.all(2.w),
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ color: '#F3F3F3'.color,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(48.w),
|
|
|
|
|
+ ),
|
|
|
|
|
+ height: 32.w,
|
|
|
|
|
+ child: TabBar(
|
|
|
|
|
+ controller: controller.tabController,
|
|
|
|
|
+ indicator: BoxDecoration(
|
|
|
|
|
+ color: ColorName.colorPrimary,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(48.w),
|
|
|
|
|
+ ),
|
|
|
|
|
+ dividerHeight: 0,
|
|
|
|
|
+ indicatorSize: TabBarIndicatorSize.tab,
|
|
|
|
|
+ unselectedLabelStyle:
|
|
|
|
|
+ TextStyle(fontSize: 14.sp, color: '#666666'.color),
|
|
|
|
|
+ labelStyle: TextStyle(fontSize: 14.sp, color: ColorName.white),
|
|
|
|
|
+ tabs: [
|
|
|
|
|
+ Tab(text: StringName.trackHistory),
|
|
|
|
|
+ Tab(text: StringName.trackNowLocation)
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildTrackHistoryContentView() {
|
|
|
|
|
+ return Column(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(height: 10.w),
|
|
|
|
|
+ Builder(builder: (context) {
|
|
|
|
|
+ return GestureDetector(
|
|
|
|
|
+ onTap: () {
|
|
|
|
|
+ controller.onTrackStartTimeClick(context);
|
|
|
|
|
+ },
|
|
|
|
|
+ child: Padding(
|
|
|
|
|
+ padding: EdgeInsets.symmetric(vertical: 9.w),
|
|
|
|
|
+ child: Row(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(width: 14.w),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ StringName.trackStartTime,
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ fontSize: 14.sp,
|
|
|
|
|
+ color: ColorName.black80,
|
|
|
|
|
+ fontWeight: FontWeight.bold),
|
|
|
|
|
+ ),
|
|
|
|
|
+ Spacer(),
|
|
|
|
|
+ Obx(() {
|
|
|
|
|
+ return Text(
|
|
|
|
|
+ controller.trackStartTime?.format('yyyy-MM-dd HH:mm') ??
|
|
|
|
|
+ '',
|
|
|
|
|
+ style:
|
|
|
|
|
+ TextStyle(fontSize: 14.sp, color: ColorName.black50),
|
|
|
|
|
+ );
|
|
|
|
|
+ }),
|
|
|
|
|
+ SizedBox(width: 6.w),
|
|
|
|
|
+ Assets.images.iconTrackSelectTimeArrow
|
|
|
|
|
+ .image(width: 16.w, height: 16.w),
|
|
|
|
|
+ SizedBox(width: 14.w),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ }),
|
|
|
|
|
+ Builder(builder: (context) {
|
|
|
|
|
+ return GestureDetector(
|
|
|
|
|
+ onTap: () {
|
|
|
|
|
+ controller.onTrackEndTimeClick(context);
|
|
|
|
|
+ },
|
|
|
|
|
+ child: Padding(
|
|
|
|
|
+ padding: EdgeInsets.symmetric(vertical: 9.w),
|
|
|
|
|
+ child: Row(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(width: 14.w),
|
|
|
|
|
+ Text(
|
|
|
|
|
+ StringName.trackEndTime,
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ fontSize: 14.sp,
|
|
|
|
|
+ color: ColorName.black80,
|
|
|
|
|
+ fontWeight: FontWeight.bold),
|
|
|
|
|
+ ),
|
|
|
|
|
+ Spacer(),
|
|
|
|
|
+ Obx(() {
|
|
|
|
|
+ return Text(
|
|
|
|
|
+ controller.trackEndTime?.format('yyyy-MM-dd HH:mm') ?? '',
|
|
|
|
|
+ style:
|
|
|
|
|
+ TextStyle(fontSize: 14.sp, color: ColorName.black50),
|
|
|
|
|
+ );
|
|
|
|
|
+ }),
|
|
|
|
|
+ SizedBox(width: 6.w),
|
|
|
|
|
+ Assets.images.iconTrackSelectTimeArrow
|
|
|
|
|
+ .image(width: 16.w, height: 16.w),
|
|
|
|
|
+ SizedBox(width: 14.w),
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ );
|
|
|
|
|
+ }),
|
|
|
|
|
+ SizedBox(height: 12.w),
|
|
|
|
|
+ Obx(() {
|
|
|
|
|
+ return Visibility(
|
|
|
|
|
+ visible: controller.startAddress != null ||
|
|
|
|
|
+ controller.endAddress != null,
|
|
|
|
|
+ child: Container(
|
|
|
|
|
+ padding: EdgeInsets.all(12.w),
|
|
|
|
|
+ margin: EdgeInsets.symmetric(horizontal: 14.w),
|
|
|
|
|
+ width: double.infinity,
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ color: '#E5F8F8F8'.color,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(12.w),
|
|
|
|
|
+ ),
|
|
|
|
|
+ child: Column(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ buildAddressInfoView(
|
|
|
|
|
+ '#12C172'.color,
|
|
|
|
|
+ StringName.trackStartLocation,
|
|
|
|
|
+ controller.startAddress ?? ''),
|
|
|
|
|
+ Align(
|
|
|
|
|
+ alignment: Alignment.centerLeft,
|
|
|
|
|
+ child: Container(
|
|
|
|
|
+ margin: EdgeInsets.only(left: 3.5.w),
|
|
|
|
|
+ child: Assets.images.bgTrackLocationTie
|
|
|
|
|
+ .image(width: 1.5.w))),
|
|
|
|
|
+ buildAddressInfoView(
|
|
|
|
|
+ '#F3353A'.color,
|
|
|
|
|
+ StringName.trackEndLocation,
|
|
|
|
|
+ controller.endAddress ?? ''),
|
|
|
|
|
+ ],
|
|
|
|
|
+ )),
|
|
|
|
|
+ );
|
|
|
|
|
+ })
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildAddressInfoView(Color color, String title, String content) {
|
|
|
|
|
+ return Row(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ Container(
|
|
|
|
|
+ width: 10.w,
|
|
|
|
|
+ height: 10.w,
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ shape: BoxShape.circle,
|
|
|
|
|
+ border: Border.all(color: color, width: 2.w),
|
|
|
|
|
+ ),
|
|
|
|
|
+ ),
|
|
|
|
|
+ SizedBox(width: 11.w),
|
|
|
|
|
+ Text(title,
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ fontSize: 13.sp,
|
|
|
|
|
+ color: ColorName.black80,
|
|
|
|
|
+ fontWeight: FontWeight.bold)),
|
|
|
|
|
+ Expanded(
|
|
|
|
|
+ child: Text(content,
|
|
|
|
|
+ style: TextStyle(fontSize: 13.sp, color: ColorName.black70)),
|
|
|
|
|
+ )
|
|
|
|
|
+ ],
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Widget buildTrackNowContentView() {
|
|
|
|
|
+ return Column(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(height: 20.w),
|
|
|
|
|
+ Row(
|
|
|
|
|
+ children: [
|
|
|
|
|
+ SizedBox(width: 12.w),
|
|
|
|
|
+ Assets.images.iconTrackLocationNow.image(width: 20.w, height: 20.w),
|
|
|
|
|
+ SizedBox(width: 3.w),
|
|
|
|
|
+ Obx(() {
|
|
|
|
|
+ return RelativeTimeText(
|
|
|
|
|
+ startPerchText: '当前位置·',
|
|
|
|
|
+ endPerchText:
|
|
|
|
|
+ controller.currentLocation?.lastUpdateTime == null
|
|
|
|
|
+ ? ''
|
|
|
|
|
+ : '更新',
|
|
|
|
|
+ timestamp: controller.currentLocation?.lastUpdateTime,
|
|
|
|
|
+ updateInterval: Duration(minutes: 1),
|
|
|
|
|
+ style: TextStyle(
|
|
|
|
|
+ fontSize: 15.sp,
|
|
|
|
|
+ color: '#333333'.color,
|
|
|
|
|
+ fontWeight: FontWeight.bold));
|
|
|
|
|
+ })
|
|
|
|
|
+ ],
|
|
|
|
|
+ ),
|
|
|
|
|
+ SizedBox(height: 16.w),
|
|
|
|
|
+ Container(
|
|
|
|
|
+ width: double.infinity,
|
|
|
|
|
+ margin: EdgeInsets.symmetric(horizontal: 12.w),
|
|
|
|
|
+ padding: EdgeInsets.all(14.w),
|
|
|
|
|
+ decoration: BoxDecoration(
|
|
|
|
|
+ color: '#F9F9F9'.color,
|
|
|
|
|
+ borderRadius: BorderRadius.circular(6.w),
|
|
|
|
|
+ ),
|
|
|
|
|
+ child: Obx(() {
|
|
|
|
|
+ return Text(controller.currentLocation?.address ?? '--',
|
|
|
|
|
+ style: TextStyle(fontSize: 14.sp, color: '#666666'.color));
|
|
|
|
|
+ }),
|
|
|
|
|
+ )
|
|
|
],
|
|
],
|
|
|
);
|
|
);
|
|
|
}
|
|
}
|