import 'package:flutter/cupertino.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:get/get_core/src/get_main.dart'; import 'package:injectable/injectable.dart'; import 'package:location/base/base_controller.dart'; import 'package:location/data/repositories/account_repository.dart'; import 'package:location/handler/error_handler.dart'; import 'package:location/sdk/map/map_helper.dart'; import 'package:location/utils/atmob_log.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import 'package:sliding_sheet2/sliding_sheet2.dart'; import '../../../data/bean/user_info.dart'; import '../../../dialog/common_confirm_dialog_impl.dart'; import '../../../dialog/location_permission_dialog.dart'; import '../../../resource/string.gen.dart'; import '../../../utils/de_bounce.dart'; import '../../../utils/permission_util.dart'; import '../../../utils/toast_util.dart'; @injectable class CommonPointSelectAddressController extends BaseController { final TextEditingController searchEditController = TextEditingController(); final FocusNode searchFocusNode = FocusNode(); final mapController = MapController.create(); final SheetController sheetController = SheetController(); final RxDouble _commonPointRange = RxDouble(200); double get commonPointRange => _commonPointRange.value; final RxDouble _sheetProgress = 0.0.obs; double get sheetProgress => _sheetProgress.value; bool _isRangeChanging = false; bool _isFirstMoveCamera = true; UserInfo get mineUserInfo => accountRepository.mineUserInfo.value; RxList poiList = RxList(); final refreshController = RefreshController(initialRefresh: false); final Debounce _searchDebounce = Debounce(debounceTime: 500); final AccountRepository accountRepository; CommonPointSelectAddressController(this.accountRepository); final MapPadding mapPadding = MapPadding(top: 80, left: 80, right: 80, bottom: 80); final CircleOptions circleOptions = CircleOptions( fillColor: '#4D7B7DFF', strokeWidth: 2.w, strokeColor: '#92AEE6'); final PoiQuery _poiQuery = PoiQuery(); final int _pageSize = 20; int _pageNum = 1; @override void onReady() { super.onReady(); _updateCurrentLocation(); mapController.setOnCameraChangeListener( (camera) { if (_isRangeChanging) { return; } if (camera.function == CameraChangeType.onCameraChange) { //暂时隐藏范围 if (circleOptions.visible == true) { circleOptions.visible = false; _updateOrAddCircle(); } } else { circleOptions ..radius = commonPointRange ..longitude = camera.position.longitude ..visible = true ..latitude = camera.position.latitude; _updateOrAddCircle(); if (_isFirstMoveCamera) { _isFirstMoveCamera = false; _moveCameraToBounds(); } //重新还原数据 _resetPoiQuery(); _poiSearch(); } }, ); } void _resetPoiQuery() { _pageNum = 1; } void _poiSearch() async { _searchDebounce.onClick(() { AtmobLog.d('zk', '_poiSearch: $_poiQuery'); FlutterMap.paginatePoiSearch( pageNum: _pageNum, pageSize: _pageSize, query: _poiQuery, bound: PoiSearchBound.circle( center: LatLng( latitude: circleOptions.latitude, longitude: circleOptions.longitude), radius: circleOptions.radius?.toInt())) .then((list) { if (_pageNum == 1) { poiList.clear(); } if (list != null && list.isNotEmpty) { poiList.addAll(list); refreshController.loadComplete(); } if (list == null || list.length < _pageSize) { refreshController.loadNoData(); } }).catchError((error) { ErrorHandler.toastError(error); refreshController.loadFailed(); }); }); } void _updateOrAddCircle() { mapController.updateOrAddCircle('DC', circleOptions); } void backClick() { if (sheetController.state?.isExpanded == true) { sheetController.snapToExtent(0, duration: const Duration(milliseconds: 250)); return; } Get.back(); } void setCommonPointRange(double value) { _commonPointRange.value = value; circleOptions.radius = value; if (circleOptions.visible == true) { _updateOrAddCircle(); _moveCameraToBounds(); } } _moveCameraToBounds() { final latLngBounds = CameraUpdateUtil.getBounds(circleOptions.latitude, circleOptions.longitude, circleOptions.radius ?? 0); if (latLngBounds != null) { mapController.moveCameraToBounds(latLngBounds, mapPadding: mapPadding); } } setSheetProgress(double progress) { _sheetProgress.value = progress; if (progress == 1) { // _requestFocus(); } } void onOpenSearchAddressModel() async { if (sheetProgress == 0) { _setExpand(); } } void _setExpand() async { await sheetController.snapToExtent(1, duration: const Duration(milliseconds: 250)); _requestFocus(); } void _requestFocus() async { if (searchFocusNode.hasFocus) { return; } //获取焦点 await Future.delayed(Duration(milliseconds: 150)); searchFocusNode.requestFocus(); } void setCommonPointRangeStart() { _isRangeChanging = true; } void setCommonPointRangeEnd() { _isRangeChanging = false; } void moveToCurrentLocation() async { //权限检查 bool isGranted = await PermissionUtil.checkLocationPermission(); if (!isGranted) { LocationPermissionDialog.show(onNextStep: _requestLocationPermission); } else { _updateCurrentLocation(); } } void _updateCurrentLocation() { var lastLocation = MapHelper.getLastLocation(); if (lastLocation == null) { locationListener(MapLocation location) { MapHelper.removeLocationListener(locationListener); _showCurrentRange(location); } MapHelper.addLocationListener(locationListener); } else { _showCurrentRange(lastLocation); } } void _showCurrentRange(MapLocation location) { circleOptions.latitude = location.latitude; circleOptions.longitude = location.longitude; _moveCameraToBounds(); } void _requestLocationPermission() async { bool isGranted = await PermissionUtil.requestLocationPermission(); if (isGranted) { _showLocationAlways(); _updateCurrentLocation(); } else { permissionRefuseDialog(settingClick: () { openAppSettings(); }); ToastUtil.show(StringName.permissionRequestFail); } } void _showLocationAlways() async { bool isGranted = await PermissionUtil.checkShowLocationAlways(); if (!isGranted) { LocationAlwaysPermissionDialog.show(onNextStep: () async { isGranted = await PermissionUtil.requestShowLocationAlways(); if (isGranted) { _updateCurrentLocation(); } }); } } onPoiItemClick(PoiItem item) {} void onLoadMorePoiData() { _pageNum++; _poiSearch(); } }