location_permission_dialog.dart 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. import 'dart:io';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
  5. import 'package:get/get.dart';
  6. import 'package:location/resource/assets.gen.dart';
  7. import 'package:location/resource/colors.gen.dart';
  8. import 'package:location/resource/string.gen.dart';
  9. import 'package:location/utils/common_expand.dart';
  10. import '../utils/common_style.dart';
  11. import 'common_confirm_dialog.dart';
  12. class LocationPermissionDialog {
  13. static const String _tag = "LocationPermissionDialog";
  14. static void show({required VoidCallback onNextStep}) {
  15. SmartDialog.show(
  16. tag: _tag,
  17. builder: (_) {
  18. if (Platform.isAndroid) {
  19. return AndroidLocationView(onNextStep: onNextStep);
  20. } else {
  21. return CupertinoLocationView(onNextStep: onNextStep);
  22. }
  23. });
  24. }
  25. static void dismiss() {
  26. SmartDialog.dismiss(tag: _tag);
  27. }
  28. }
  29. class AndroidLocationView extends Dialog {
  30. final VoidCallback onNextStep;
  31. const AndroidLocationView({super.key, required this.onNextStep});
  32. @override
  33. Widget build(BuildContext context) {
  34. return CommonConfirmView(
  35. titleWidget: Text(StringName.kindlyReminder,
  36. style: TextStyle(
  37. fontSize: 17.sp,
  38. color: '#333333'.color,
  39. fontWeight: FontWeight.bold)),
  40. descWidget: Text(StringName.dialogLocationPermissionTips,
  41. style: TextStyle(fontSize: 15.sp, color: '#404040'.color)),
  42. confirmText: StringName.dialogLocationPermissionConfirmTxt,
  43. cancelOnTap: () {
  44. LocationPermissionDialog.dismiss();
  45. },
  46. confirmOnTap: () {
  47. LocationPermissionDialog.dismiss();
  48. onNextStep.call();
  49. });
  50. }
  51. }
  52. class CupertinoLocationView extends Dialog {
  53. final VoidCallback onNextStep;
  54. const CupertinoLocationView({super.key, required this.onNextStep});
  55. @override
  56. Widget build(BuildContext context) {
  57. return IntrinsicHeight(
  58. child: Container(
  59. width: 300.w,
  60. decoration: BoxDecoration(
  61. color: Colors.white,
  62. borderRadius: BorderRadius.circular(10.w),
  63. ),
  64. child: Column(
  65. children: [
  66. AspectRatio(
  67. aspectRatio: 900 / 438,
  68. child: Assets.images.bgDialogLocationPermissionIos
  69. .image(width: double.infinity),
  70. ),
  71. SizedBox(height: 34.w),
  72. SizedBox(
  73. width: 210.w,
  74. child: RichText(
  75. textAlign: TextAlign.center,
  76. text: TextSpan(
  77. style: TextStyle(fontSize: 14.sp, color: '#404040'.color),
  78. children: [
  79. TextSpan(text: '为保位置展示在地图上,需要允许使用'),
  80. TextSpan(
  81. text: '位置权限',
  82. style: TextStyle(
  83. color: '#1448CC'.color,
  84. fontWeight: FontWeight.bold)),
  85. ]),
  86. ),
  87. ),
  88. SizedBox(height: 19.w),
  89. GestureDetector(
  90. onTap: () {
  91. LocationPermissionDialog.dismiss();
  92. onNextStep.call();
  93. },
  94. child: Container(
  95. width: 252.w,
  96. height: 36.w,
  97. decoration: getPrimaryBtnDecoration(46.w),
  98. child: Center(
  99. child: Text(StringName.nextStep,
  100. style: TextStyle(
  101. fontSize: 16.sp,
  102. color: Colors.white,
  103. fontWeight: FontWeight.bold)),
  104. ),
  105. ),
  106. ),
  107. SizedBox(height: 23.w),
  108. ],
  109. ),
  110. ),
  111. );
  112. }
  113. }
  114. class LocationAlwaysPermissionDialog {
  115. static const String _tag = "LocationAlwaysPermissionDialog";
  116. static void show({required VoidCallback onNextStep}) {
  117. SmartDialog.show(
  118. tag: _tag,
  119. alignment:
  120. Platform.isAndroid ? Alignment.center : Alignment.bottomCenter,
  121. builder: (_) {
  122. if (Platform.isAndroid) {
  123. return AndroidLocationAlwaysView(onNextStep: onNextStep);
  124. } else {
  125. return CupertinoLocationAlwaysView(onNextStep: onNextStep);
  126. }
  127. });
  128. }
  129. static void dismiss() {
  130. SmartDialog.dismiss(tag: _tag);
  131. }
  132. }
  133. class AndroidLocationAlwaysView extends Dialog {
  134. final VoidCallback onNextStep;
  135. const AndroidLocationAlwaysView({super.key, required this.onNextStep});
  136. @override
  137. Widget build(BuildContext context) {
  138. return CommonConfirmView(
  139. titleWidget: Text(StringName.dialogLocationAlwaysPermissionTitle,
  140. style: TextStyle(
  141. fontSize: 17.sp,
  142. color: '#333333'.color,
  143. fontWeight: FontWeight.bold)),
  144. descWidget: RichText(
  145. text: TextSpan(
  146. style: TextStyle(fontSize: 15.sp, color: '#404040'.color),
  147. children: [
  148. TextSpan(text: '如需要定位实时更新您的位置,需要在后台访问您的位置,避免轨迹缺失,请在定位权限中选择'),
  149. TextSpan(
  150. text: '“始终允许”',
  151. style: TextStyle(color: ColorName.colorPrimary)),
  152. ])),
  153. confirmText: StringName.dialogLocationAlwaysPermissionConfirmTxt,
  154. cancelOnTap: () {
  155. LocationAlwaysPermissionDialog.dismiss();
  156. },
  157. confirmOnTap: () {
  158. LocationAlwaysPermissionDialog.dismiss();
  159. onNextStep.call();
  160. });
  161. }
  162. }
  163. class CupertinoLocationAlwaysView extends Dialog {
  164. final VoidCallback onNextStep;
  165. final RxInt _currentPage = 0.obs;
  166. int get currentPage => _currentPage.value;
  167. final PageController pageController = PageController(initialPage: 0);
  168. final List<Widget> pageList = [
  169. Assets.images.imgDialogLocationAlwaysTip1.image(width: double.infinity),
  170. Assets.images.imgDialogLocationAlwaysTip2.image(width: double.infinity),
  171. Assets.images.imgDialogLocationAlwaysTip3.image(width: double.infinity),
  172. ];
  173. CupertinoLocationAlwaysView({super.key, required this.onNextStep});
  174. @override
  175. Widget build(BuildContext context) {
  176. return IntrinsicHeight(
  177. child: Container(
  178. width: double.infinity,
  179. decoration: BoxDecoration(
  180. color: Colors.white,
  181. borderRadius: BorderRadius.only(
  182. topLeft: Radius.circular(16.w),
  183. topRight: Radius.circular(16.w),
  184. ),
  185. ),
  186. child: Column(
  187. mainAxisAlignment: MainAxisAlignment.center,
  188. children: [
  189. SizedBox(height: 28.w),
  190. Container(
  191. margin: EdgeInsets.symmetric(horizontal: 16.w),
  192. child: RichText(
  193. text: TextSpan(
  194. style: TextStyle(fontSize: 20.sp, color: '#333333'.color),
  195. children: [
  196. TextSpan(
  197. text: '应用使用需开启',
  198. style: TextStyle(fontWeight: FontWeight.bold)),
  199. TextSpan(
  200. text: '精准位置',
  201. style: TextStyle(
  202. color: '#1448CC'.color,
  203. fontWeight: FontWeight.bold)),
  204. TextSpan(
  205. text: '权限',
  206. style: TextStyle(fontWeight: FontWeight.bold))
  207. ]),
  208. ),
  209. ),
  210. Text(StringName.locationBackgroundAlwaysDesc,
  211. style: TextStyle(fontSize: 14.sp, color: '#666666'.color)),
  212. SizedBox(height: 24.w),
  213. SizedBox(
  214. width: 304.w,
  215. height: 230.w,
  216. child: PageView(
  217. onPageChanged: (index) {
  218. _currentPage.value = index;
  219. },
  220. controller: pageController,
  221. children: pageList,
  222. ),
  223. ),
  224. SizedBox(height: 8.w),
  225. indicator(),
  226. SizedBox(height: 30.w),
  227. GestureDetector(
  228. onTap: () => onNextClick(),
  229. child: Container(
  230. decoration: getPrimaryBtnDecoration(46.w),
  231. width: 312.w,
  232. height: 44.w,
  233. child: Center(
  234. child: Text(StringName.nextStep,
  235. style: TextStyle(fontSize: 15.sp, color: Colors.white)),
  236. ),
  237. ),
  238. ),
  239. SizedBox(height: 28.w),
  240. ],
  241. ),
  242. ),
  243. );
  244. }
  245. Widget indicator() {
  246. return Obx(() {
  247. return Row(
  248. mainAxisAlignment: MainAxisAlignment.center,
  249. children: List.generate(pageList.length, (index) {
  250. return Container(
  251. margin: EdgeInsets.symmetric(horizontal: 3.w),
  252. width: 6.w,
  253. height: 6.w,
  254. decoration: BoxDecoration(
  255. color: currentPage == index ? '#A7A7A7'.color : '#E5E5E5'.color,
  256. shape: BoxShape.circle,
  257. ),
  258. );
  259. }),
  260. );
  261. });
  262. }
  263. void onNextClick() async {
  264. double? index = pageController.page;
  265. if (index == pageList.length - 1) {
  266. LocationAlwaysPermissionDialog.dismiss();
  267. onNextStep.call();
  268. return;
  269. }
  270. await pageController.nextPage(
  271. duration: const Duration(milliseconds: 300), curve: Curves.easeInOut);
  272. }
  273. }