Parcourir la source

[new]增加首页定位授权流程

zk il y a 8 mois
Parent
commit
8dd82e7ca1

BIN
assets/images/bg_dialog_location_permission_ios.webp


BIN
assets/images/img_dialog_location_always_tip_1.webp


BIN
assets/images/img_dialog_location_always_tip_2.webp


BIN
assets/images/img_dialog_location_always_tip_3.webp


+ 3 - 0
assets/string/base/string.xml

@@ -98,4 +98,7 @@
     <string name="dialog_exit_account_title">提示</string>
     <string name="dialog_exit_account_desc">确定退出登录吗?</string>
 
+    <string name="next_step">下一步</string>
+    <string name="location_background_always_desc">为保位置展示在地图上,请按照图中指引操作</string>
+
 </resources>

+ 239 - 0
lib/dialog/location_permission_dialog.dart

@@ -0,0 +1,239 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:get/get.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 '../utils/common_style.dart';
+
+class LocationPermissionDialog {
+  static const String _tag = "LocationPermissionDialog";
+
+  static void show({required VoidCallback onNextStep}) {
+    SmartDialog.show(
+        tag: _tag,
+        builder: (_) {
+          if (Platform.isAndroid) {
+            return CupertinoLocationView(onNextStep: onNextStep);
+          } else {
+            return CupertinoLocationView(onNextStep: onNextStep);
+          }
+        });
+  }
+
+  static void dismiss() {
+    SmartDialog.dismiss(tag: _tag);
+  }
+}
+
+class AndroidLocationView extends Dialog {
+  const AndroidLocationView({super.key});
+}
+
+class CupertinoLocationView extends Dialog {
+  final VoidCallback onNextStep;
+
+  const CupertinoLocationView({super.key, required this.onNextStep});
+
+  @override
+  Widget build(BuildContext context) {
+    return IntrinsicHeight(
+      child: Container(
+        width: 300.w,
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.circular(10.w),
+        ),
+        child: Column(
+          children: [
+            Assets.images.bgDialogLocationPermissionIos
+                .image(width: double.infinity),
+            SizedBox(height: 34.w),
+            SizedBox(
+              width: 210.w,
+              child: RichText(
+                textAlign: TextAlign.center,
+                text: TextSpan(
+                    style: TextStyle(fontSize: 14.sp, color: '#404040'.color),
+                    children: [
+                      TextSpan(text: '为保位置展示在地图上,需要允许使用'),
+                      TextSpan(
+                          text: '位置权限',
+                          style: TextStyle(
+                              color: '#1448CC'.color,
+                              fontWeight: FontWeight.bold)),
+                    ]),
+              ),
+            ),
+            SizedBox(height: 19.w),
+            GestureDetector(
+              onTap: () {
+                LocationPermissionDialog.dismiss();
+                onNextStep.call();
+              },
+              child: Container(
+                width: 252.w,
+                height: 36.w,
+                decoration: getPrimaryBtnDecoration(46.w),
+                child: Center(
+                  child: Text(StringName.nextStep,
+                      style: TextStyle(
+                          fontSize: 16.sp,
+                          color: Colors.white,
+                          fontWeight: FontWeight.bold)),
+                ),
+              ),
+            ),
+            SizedBox(height: 23.w),
+          ],
+        ),
+      ),
+    );
+  }
+}
+
+class LocationAlwaysPermissionDialog {
+  static const String _tag = "LocationAlwaysPermissionDialog";
+
+  static void show({required VoidCallback onNextStep}) {
+    SmartDialog.show(
+        tag: _tag,
+        alignment: Alignment.bottomCenter,
+        builder: (_) {
+          if (Platform.isAndroid) {
+            return CupertinoLocationAlwaysView(onNextStep: onNextStep);
+          } else {
+            return CupertinoLocationAlwaysView(onNextStep: onNextStep);
+          }
+        });
+  }
+
+  static void dismiss() {
+    SmartDialog.dismiss(tag: _tag);
+  }
+}
+
+class CupertinoLocationAlwaysView extends Dialog {
+  final VoidCallback onNextStep;
+
+  final RxInt _currentPage = 0.obs;
+
+  int get currentPage => _currentPage.value;
+
+  final PageController pageController = PageController(initialPage: 0);
+
+  final List<Widget> pageList = [
+    Assets.images.imgDialogLocationAlwaysTip1.image(width: double.infinity),
+    Assets.images.imgDialogLocationAlwaysTip2.image(width: double.infinity),
+    Assets.images.imgDialogLocationAlwaysTip3.image(width: double.infinity),
+  ];
+
+  CupertinoLocationAlwaysView({super.key, required this.onNextStep});
+
+  @override
+  Widget build(BuildContext context) {
+    return IntrinsicHeight(
+      child: Container(
+        width: double.infinity,
+        decoration: BoxDecoration(
+          color: Colors.white,
+          borderRadius: BorderRadius.only(
+            topLeft: Radius.circular(16.w),
+            topRight: Radius.circular(16.w),
+          ),
+        ),
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            SizedBox(height: 28.w),
+            Container(
+              margin: EdgeInsets.symmetric(horizontal: 16.w),
+              child: RichText(
+                text: TextSpan(
+                    style: TextStyle(fontSize: 20.sp, color: '#333333'.color),
+                    children: [
+                      TextSpan(
+                          text: '应用使用需开启',
+                          style: TextStyle(fontWeight: FontWeight.bold)),
+                      TextSpan(
+                          text: '精准位置',
+                          style: TextStyle(
+                              color: '#1448CC'.color,
+                              fontWeight: FontWeight.bold)),
+                      TextSpan(
+                          text: '权限',
+                          style: TextStyle(fontWeight: FontWeight.bold))
+                    ]),
+              ),
+            ),
+            Text(StringName.locationBackgroundAlwaysDesc,
+                style: TextStyle(fontSize: 14.sp, color: '#666666'.color)),
+            SizedBox(height: 24.w),
+            SizedBox(
+              width: 304.w,
+              height: 230.w,
+              child: PageView(
+                onPageChanged: (index) {
+                  _currentPage.value = index;
+                },
+                controller: pageController,
+                children: pageList,
+              ),
+            ),
+            SizedBox(height: 8.w),
+            indicator(),
+            SizedBox(height: 30.w),
+            GestureDetector(
+              onTap: () => onNextClick(),
+              child: Container(
+                decoration: getPrimaryBtnDecoration(46.w),
+                width: 312.w,
+                height: 44.w,
+                child: Center(
+                  child: Text(StringName.nextStep,
+                      style: TextStyle(fontSize: 15.sp, color: Colors.white)),
+                ),
+              ),
+            ),
+            SizedBox(height: 28.w),
+          ],
+        ),
+      ),
+    );
+  }
+
+  Widget indicator() {
+    return Obx(() {
+      return Row(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children: List.generate(pageList.length, (index) {
+          return Container(
+            margin: EdgeInsets.symmetric(horizontal: 3.w),
+            width: 6.w,
+            height: 6.w,
+            decoration: BoxDecoration(
+              color: currentPage == index ? '#A7A7A7'.color : '#E5E5E5'.color,
+              shape: BoxShape.circle,
+            ),
+          );
+        }),
+      );
+    });
+  }
+
+  void onNextClick() async {
+    double? index = pageController.page;
+    if (index == pageList.length - 1) {
+      LocationAlwaysPermissionDialog.dismiss();
+      onNextStep.call();
+      return;
+    }
+    await pageController.nextPage(
+        duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
+  }
+}

+ 34 - 0
lib/module/main/main_controller.dart

@@ -1,3 +1,5 @@
+import 'dart:io';
+
 import 'package:get/get.dart';
 import 'package:get/get_rx/src/rx_types/rx_types.dart';
 import 'package:injectable/injectable.dart';
@@ -10,6 +12,8 @@ import 'package:location/utils/atmob_log.dart';
 import 'package:map/flutter_map.dart';
 import 'package:map_platform_interface/map_interface.dart';
 
+import '../../dialog/location_permission_dialog.dart';
+import '../../utils/location_permission_util.dart';
 import '../add_friend/add_friend_view.dart';
 import '../mine/mine_page.dart';
 
@@ -99,4 +103,34 @@ class MainController extends BaseController {
     }
     onSelectClick(userInfo);
   }
+
+  void onCurrentLocationClick() async {
+    //权限检查
+    bool isGranted = await LocationPermissionUtil.checkLocationPermission();
+    if (!isGranted) {
+      LocationPermissionDialog.show(onNextStep: () async {
+        isGranted = await LocationPermissionUtil.requestLocationPermission();
+        _showLocationAlways();
+        if (isGranted) {
+          _updateCurrentLocation();
+        }
+      });
+    } else {
+      _updateCurrentLocation();
+    }
+  }
+
+  void _showLocationAlways() async {
+    bool isGranted = await LocationPermissionUtil.checkShowLocationAlways();
+    if (!isGranted) {
+      LocationAlwaysPermissionDialog.show(onNextStep: () async {
+        isGranted = await LocationPermissionUtil.requestShowLocationAlways();
+        if (isGranted) {
+          _updateCurrentLocation();
+        }
+      });
+    }
+  }
+
+  void _updateCurrentLocation() {}
 }

+ 7 - 4
lib/module/main/main_page.dart

@@ -66,10 +66,13 @@ class MainPage extends BasePage<MainController> {
                               child: Assets.images.iconMainRefreshFriendLocation
                                   .image(width: 42.w, height: 42.w)),
                           SizedBox(height: 14.w),
-                          Container(
-                              margin: EdgeInsets.only(right: 12.w),
-                              child: Assets.images.iconMainRefreshMineLocation
-                                  .image(width: 42.w, height: 42.w)),
+                          GestureDetector(
+                            onTap: controller.onCurrentLocationClick,
+                            child: Container(
+                                margin: EdgeInsets.only(right: 12.w),
+                                child: Assets.images.iconMainRefreshMineLocation
+                                    .image(width: 42.w, height: 42.w)),
+                          ),
                           SizedBox(height: 20.w)
                         ],
                       ),

+ 21 - 1
lib/resource/assets.gen.dart

@@ -16,6 +16,10 @@ class $AssetsImagesGen {
   AssetGenImage get bgAddFriendDialog =>
       const AssetGenImage('assets/images/bg_add_friend_dialog.webp');
 
+  /// File path: assets/images/bg_dialog_location_permission_ios.webp
+  AssetGenImage get bgDialogLocationPermissionIos => const AssetGenImage(
+      'assets/images/bg_dialog_location_permission_ios.webp');
+
   /// File path: assets/images/bg_login_head_container.webp
   AssetGenImage get bgLoginHeadContainer =>
       const AssetGenImage('assets/images/bg_login_head_container.webp');
@@ -176,9 +180,22 @@ class $AssetsImagesGen {
   AssetGenImage get iconWhiteBack =>
       const AssetGenImage('assets/images/icon_white_back.webp');
 
+  /// File path: assets/images/img_dialog_location_always_tip_1.webp
+  AssetGenImage get imgDialogLocationAlwaysTip1 => const AssetGenImage(
+      'assets/images/img_dialog_location_always_tip_1.webp');
+
+  /// File path: assets/images/img_dialog_location_always_tip_2.webp
+  AssetGenImage get imgDialogLocationAlwaysTip2 => const AssetGenImage(
+      'assets/images/img_dialog_location_always_tip_2.webp');
+
+  /// File path: assets/images/img_dialog_location_always_tip_3.webp
+  AssetGenImage get imgDialogLocationAlwaysTip3 => const AssetGenImage(
+      'assets/images/img_dialog_location_always_tip_3.webp');
+
   /// List of all assets
   List<AssetGenImage> get values => [
         bgAddFriendDialog,
+        bgDialogLocationPermissionIos,
         bgLoginHeadContainer,
         bgMineMemberCard,
         bgPageBackground,
@@ -218,7 +235,10 @@ class $AssetsImagesGen {
         iconMineUnlockVip,
         iconSplashTitle,
         iconVip,
-        iconWhiteBack
+        iconWhiteBack,
+        imgDialogLocationAlwaysTip1,
+        imgDialogLocationAlwaysTip2,
+        imgDialogLocationAlwaysTip3
       ];
 }
 

+ 5 - 0
lib/resource/string.gen.dart

@@ -106,6 +106,9 @@ class StringName {
       'dialog_exit_account_title'.tr; // 提示
   static final String dialogExitAccountDesc =
       'dialog_exit_account_desc'.tr; // 确定退出登录吗?
+  static final String nextStep = 'next_step'.tr; // 下一步
+  static final String locationBackgroundAlwaysDesc =
+      'location_background_always_desc'.tr; // 为保位置展示在地图上,请按照图中指引操作
 }
 class StringMultiSource {
   StringMultiSource._();
@@ -190,6 +193,8 @@ class StringMultiSource {
       'dialog_sure': '确定',
       'dialog_exit_account_title': '提示',
       'dialog_exit_account_desc': '确定退出登录吗?',
+      'next_step': '下一步',
+      'location_background_always_desc': '为保位置展示在地图上,请按照图中指引操作',
     },
   };
 }

+ 42 - 0
lib/utils/location_permission_util.dart

@@ -0,0 +1,42 @@
+import 'package:permission_handler/permission_handler.dart';
+
+class LocationPermissionUtil {
+  LocationPermissionUtil._();
+
+  static Future<bool> requestLocationPermission() async {
+    final status = await Permission.locationWhenInUse.request();
+    if (status.isGranted) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  static Future<bool> checkLocationPermission() async {
+    final status = await Permission.locationWhenInUse.status;
+    if (status.isGranted) {
+      return true;
+    }
+    {
+      return false;
+    }
+  }
+
+  static Future<bool> requestShowLocationAlways() async {
+    final status = await Permission.locationAlways.request();
+    if (status.isGranted) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  static Future<bool> checkShowLocationAlways() async {
+    final status = await Permission.locationAlways.status;
+    if (status.isGranted) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}

+ 1 - 1
pubspec.lock

@@ -561,7 +561,7 @@ packages:
     source: path
     version: "0.0.1"
   map_platform_interface:
-    dependency: "direct main"
+    dependency: transitive
     description:
       path: "plugins/map_platform_interface"
       relative: true

+ 0 - 3
pubspec.yaml

@@ -91,9 +91,6 @@ dependencies:
   #    path: plugins/map_google_android
   map_amap_android:
     path: plugins/map_amap_android
-
-  map_platform_interface:
-    path: plugins/map_platform_interface
   ##iOS端
   #  map_amap_ios:
   #    path: plugins/map_amap_ios