common_point_select_address_controller.dart 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import 'package:flutter/cupertino.dart';
  2. import 'package:flutter_map/flutter_map.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:get/get.dart';
  5. import 'package:get/get_core/src/get_main.dart';
  6. import 'package:injectable/injectable.dart';
  7. import 'package:location/base/base_controller.dart';
  8. import 'package:location/data/repositories/account_repository.dart';
  9. import 'package:location/handler/error_handler.dart';
  10. import 'package:location/sdk/map/map_helper.dart';
  11. import 'package:location/utils/atmob_log.dart';
  12. import 'package:permission_handler/permission_handler.dart';
  13. import 'package:pull_to_refresh/pull_to_refresh.dart';
  14. import 'package:sliding_sheet2/sliding_sheet2.dart';
  15. import '../../../data/bean/user_info.dart';
  16. import '../../../dialog/common_confirm_dialog_impl.dart';
  17. import '../../../dialog/location_permission_dialog.dart';
  18. import '../../../resource/string.gen.dart';
  19. import '../../../utils/action_limiter.dart';
  20. import '../../../utils/permission_util.dart';
  21. import '../../../utils/toast_util.dart';
  22. @injectable
  23. class CommonPointSelectAddressController extends BaseController {
  24. final TextEditingController searchEditController = TextEditingController();
  25. final FocusNode searchFocusNode = FocusNode();
  26. final mapController = MapController.create();
  27. final SheetController sheetController = SheetController();
  28. final RxDouble _commonPointRange = RxDouble(200);
  29. double get commonPointRange => _commonPointRange.value;
  30. final RxDouble _sheetProgress = 0.0.obs;
  31. double get sheetProgress => _sheetProgress.value;
  32. bool _isRangeChanging = false;
  33. bool _isFirstMoveCamera = true;
  34. UserInfo get mineUserInfo => accountRepository.mineUserInfo.value;
  35. RxList<PoiItem> poiList = RxList();
  36. final refreshController = RefreshController(initialRefresh: false);
  37. final Rxn<PoiItem> _currentRangeCenterLocation = Rxn<PoiItem>();
  38. PoiItem? get currentRangeCenterLocation => _currentRangeCenterLocation.value;
  39. bool _isUserSelectLocation = false;
  40. final ActionLimiter _debounceLimiter =
  41. ActionLimiter(milliseconds: 300, mode: LimitMode.debounce);
  42. final AccountRepository accountRepository;
  43. CommonPointSelectAddressController(this.accountRepository);
  44. final MapPadding mapPadding =
  45. MapPadding(top: 80, left: 80, right: 80, bottom: 80);
  46. final CircleOptions circleOptions = CircleOptions(
  47. fillColor: '#4D7B7DFF', strokeWidth: 2.w, strokeColor: '#92AEE6');
  48. final PoiQuery _poiQuery = PoiQuery();
  49. final int _pageSize = 20;
  50. int _pageNum = 1;
  51. @override
  52. void onReady() {
  53. super.onReady();
  54. circleOptions.radius = commonPointRange;
  55. _updateCurrentLocation();
  56. mapController.setOnCameraChangeListener(
  57. (camera) {
  58. circleOptions
  59. ..longitude = camera.position.longitude
  60. ..latitude = camera.position.latitude;
  61. if (_isRangeChanging) {
  62. return;
  63. }
  64. if (camera.function == CameraChangeType.onCameraChangeFinish) {
  65. AtmobLog.d('zk', 'onCameraChangeFinish ');
  66. circleOptions.visible = true;
  67. if (!_isUserSelectLocation) {
  68. _currentRangeCenterLocation.value = null;
  69. } else {
  70. _isUserSelectLocation = false;
  71. }
  72. _updateOrAddCircle();
  73. if (_isFirstMoveCamera) {
  74. _isFirstMoveCamera = false;
  75. _moveCameraToBounds();
  76. }
  77. //重新还原数据
  78. _resetPoiQuery();
  79. _poiSearch();
  80. } else {
  81. //暂时隐藏范围
  82. if (circleOptions.visible == true) {
  83. circleOptions.visible = false;
  84. _updateOrAddCircle();
  85. }
  86. }
  87. },
  88. );
  89. }
  90. void onSearchTextChange(String txt) {
  91. if (_poiQuery.keyWord == txt) {
  92. return;
  93. }
  94. _poiQuery.keyWord = txt;
  95. _resetPoiQuery();
  96. _poiSearch();
  97. }
  98. void _resetPoiQuery() {
  99. _pageNum = 1;
  100. }
  101. void _poiSearch() async {
  102. _debounceLimiter.run(() {
  103. AtmobLog.d('zk', '_poiSearch: $_poiQuery');
  104. FlutterMap.paginatePoiSearch(
  105. pageNum: _pageNum,
  106. pageSize: _pageSize,
  107. query: _poiQuery,
  108. bound: PoiSearchBound.circle(
  109. center: LatLng(
  110. latitude: circleOptions.latitude,
  111. longitude: circleOptions.longitude),
  112. radius: circleOptions.radius?.toInt()))
  113. .then((list) {
  114. if (_pageNum == 1) {
  115. poiList.clear();
  116. }
  117. if (list != null && list.isNotEmpty) {
  118. poiList.addAll(list);
  119. refreshController.loadComplete();
  120. }
  121. if (list == null || list.length < _pageSize) {
  122. refreshController.loadNoData();
  123. }
  124. }).catchError((error) {
  125. ErrorHandler.toastError(error);
  126. refreshController.loadFailed();
  127. });
  128. });
  129. }
  130. void _updateOrAddCircle() {
  131. mapController.updateOrAddCircle('DC', circleOptions);
  132. }
  133. void backClick() {
  134. if (sheetController.state?.isExpanded == true) {
  135. sheetController.snapToExtent(0,
  136. duration: const Duration(milliseconds: 250));
  137. return;
  138. }
  139. Get.back();
  140. }
  141. _moveCameraToBounds() {
  142. final latLngBounds = CameraUpdateUtil.getBounds(circleOptions.latitude,
  143. circleOptions.longitude, circleOptions.radius ?? 0);
  144. if (latLngBounds != null) {
  145. mapController.moveCameraToBounds(latLngBounds, mapPadding: mapPadding);
  146. }
  147. }
  148. setSheetProgress(double progress) {
  149. _sheetProgress.value = progress;
  150. if (progress == 1) {
  151. // _requestFocus();
  152. }
  153. }
  154. void onOpenSearchAddressModel() async {
  155. if (sheetProgress == 0) {
  156. _setExpand();
  157. }
  158. }
  159. void _setExpand() async {
  160. await sheetController.snapToExtent(1,
  161. duration: const Duration(milliseconds: 250));
  162. _requestFocus();
  163. }
  164. void _requestFocus() async {
  165. if (searchFocusNode.hasFocus) {
  166. return;
  167. }
  168. //获取焦点
  169. await Future.delayed(Duration(milliseconds: 150));
  170. searchFocusNode.requestFocus();
  171. }
  172. void setCommonPointRange(double value) {
  173. _commonPointRange.value = value;
  174. circleOptions.radius = value;
  175. if (circleOptions.visible == true) {
  176. _updateOrAddCircle();
  177. _moveCameraToBounds();
  178. }
  179. }
  180. void setCommonPointRangeStart() {
  181. _isRangeChanging = true;
  182. }
  183. void setCommonPointRangeEnd() {
  184. _isRangeChanging = false;
  185. _resetPoiQuery();
  186. _poiSearch();
  187. }
  188. void moveToCurrentLocation() async {
  189. //权限检查
  190. bool isGranted = await PermissionUtil.checkLocationPermission();
  191. if (!isGranted) {
  192. LocationPermissionDialog.show(onNextStep: _requestLocationPermission);
  193. } else {
  194. _updateCurrentLocation();
  195. }
  196. }
  197. void _updateCurrentLocation() {
  198. var lastLocation = MapHelper.getLastLocation();
  199. if (lastLocation == null) {
  200. locationListener(MapLocation location) {
  201. MapHelper.removeLocationListener(locationListener);
  202. _showCurrentRange(location);
  203. }
  204. MapHelper.addLocationListener(locationListener);
  205. } else {
  206. _showCurrentRange(lastLocation);
  207. }
  208. }
  209. void _showCurrentRange(MapLocation location) {
  210. circleOptions.latitude = location.latitude;
  211. circleOptions.longitude = location.longitude;
  212. _isUserSelectLocation = true;
  213. _currentRangeCenterLocation.value = PoiItem(
  214. latitude: location.latitude,
  215. longitude: location.longitude,
  216. address: location.address);
  217. _moveCameraToBounds();
  218. }
  219. void _requestLocationPermission() async {
  220. bool isGranted = await PermissionUtil.requestLocationPermission();
  221. if (isGranted) {
  222. _showLocationAlways();
  223. _updateCurrentLocation();
  224. } else {
  225. permissionRefuseDialog(settingClick: () {
  226. openAppSettings();
  227. });
  228. ToastUtil.show(StringName.permissionRequestFail);
  229. }
  230. }
  231. void _showLocationAlways() async {
  232. bool isGranted = await PermissionUtil.checkShowLocationAlways();
  233. if (!isGranted) {
  234. LocationAlwaysPermissionDialog.show(onNextStep: () async {
  235. isGranted = await PermissionUtil.requestShowLocationAlways();
  236. if (isGranted) {
  237. _updateCurrentLocation();
  238. }
  239. });
  240. }
  241. }
  242. onPoiItemClick(PoiItem item) async {
  243. _resetPoiQuery();
  244. circleOptions
  245. ..longitude = item.longitude
  246. ..latitude = item.latitude;
  247. _currentRangeCenterLocation.value = item;
  248. _isUserSelectLocation = true;
  249. _moveCameraToBounds();
  250. if (sheetController.state?.isExpanded == true) {
  251. await sheetController.scrollTo(0, duration: Duration(milliseconds: 1));
  252. sheetController.snapToExtent(0,
  253. duration: const Duration(milliseconds: 250));
  254. }
  255. }
  256. void onLoadMorePoiData() {
  257. _pageNum++;
  258. _poiSearch();
  259. }
  260. void onSelectAddressDone() {
  261. if (currentRangeCenterLocation == null) {
  262. ToastUtil.show(StringName.selectAddressPlease);
  263. return;
  264. }
  265. Get.back(result: currentRangeCenterLocation);
  266. }
  267. }