import 'dart:convert'; import 'dart:io'; import 'dart:ui'; import 'package:android_intent_plus/android_intent.dart'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_baidu_mapapi_base/flutter_baidu_mapapi_base.dart'; import 'package:flutter_baidu_mapapi_map/flutter_baidu_mapapi_map.dart'; import 'package:flutter_baidu_mapapi_utils/flutter_baidu_mapapi_utils.dart'; import 'package:flutter_bmflocation/bdmap_location_flutter_plugin.dart'; import 'package:flutter_bmflocation/flutter_baidu_location_android_option.dart'; import 'package:flutter_bmflocation/flutter_baidu_location_ios_option.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:huixiang/generated/l10n.dart'; import 'package:huixiang/retrofit/data/address.dart'; import 'package:huixiang/retrofit/retrofit_api.dart'; import 'package:huixiang/view_widget/request_permission.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class AddressMapPage extends StatefulWidget { @override State createState() { return _AddressMapPage(); } } class _AddressMapPage extends State { //加载自定义地图样式 void _loadCustomData() async { setState(() { _mapController.setCustomMapStyle('assets/map_style/chatian.sty', 0); }); } LocationFlutterPlugin aMapFlutterLocation; String city = "武汉市"; String keyWord = ""; @override void dispose() { super.dispose(); aMapFlutterLocation.stopLocation(); } ApiService apiService; @override void initState() { super.initState(); SharedPreferences.getInstance().then((value) => { apiService = ApiService(Dio(), context: context, token: value.getString('token')), }); if (aMapFlutterLocation == null) { aMapFlutterLocation = LocationFlutterPlugin(); aMapFlutterLocation.requestPermission(); aMapFlutterLocation.onResultCallback().listen((event) { print("event: ${jsonEncode(event)}"); if (event != null && event["latitude"] != null && event["longitude"] != null) { city = event["city"]; BMFCoordinate latLng; if (event["latitude"] is String && event["longitude"] is String) { latLng = BMFCoordinate(double.tryParse(event["latitude"]), double.tryParse(event["longitude"])); } else { latLng = BMFCoordinate(event["latitude"], event["longitude"]); } BMFCalculateUtils.coordConvert( coordinate: latLng, fromType: BMF_COORD_TYPE.COMMON, toType: BMF_COORD_TYPE.BD09LL) .then((value) { saveLatLng(value); if (_mapController != null) { this.latLng = Platform.isIOS ? value : latLng; addMarker(); _mapController.updateMapOptions( BMFMapOptions( center: latLng, zoomLevel: 15, ), ); } searchPoi(latLng); }); } }); } _setLocOption(); getLatLng(); startLocation(); } /// 设置android端和ios端定位参数 void _setLocOption() { /// android 端设置定位参数 BaiduLocationAndroidOption androidOption = new BaiduLocationAndroidOption(); androidOption.setCoorType("GCJ02"); // 设置返回的位置坐标系类型 androidOption.setIsNeedAltitude(true); // 设置是否需要返回海拔高度信息 androidOption.setIsNeedAddres(true); // 设置是否需要返回地址信息 androidOption.setIsNeedLocationPoiList(true); // 设置是否需要返回周边poi信息 androidOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息 androidOption.setIsNeedLocationDescribe(true); // 设置是否需要返回位置描述 androidOption.setOpenGps(true); // 设置是否需要使用gps androidOption.setLocationMode(LocationMode.Hight_Accuracy); // 设置定位模式 androidOption.setScanspan(0); // 设置发起定位请求时间间隔 Map androidMap = androidOption.getMap(); /// ios 端设置定位参数 BaiduLocationIOSOption iosOption = new BaiduLocationIOSOption(); iosOption.setIsNeedNewVersionRgc(true); // 设置是否需要返回最新版本rgc信息 iosOption.setBMKLocationCoordinateType( "BMKLocationCoordinateTypeGCJ02"); // 设置返回的位置坐标系类型 iosOption.setActivityType("CLActivityTypeAutomotiveNavigation"); // 设置应用位置类型 iosOption.setLocationTimeout(10); // 设置位置获取超时时间 iosOption.setDesiredAccuracy("kCLLocationAccuracyBest"); // 设置预期精度参数 iosOption.setReGeocodeTimeout(10); // 设置获取地址信息超时时间 iosOption.setDistanceFilter(1000); // 设置定位最小更新距离 iosOption.setAllowsBackgroundLocationUpdates(true); // 是否允许后台定位 iosOption.setPauseLocUpdateAutomatically(true); // 定位是否会被系统自动暂停 Map iosMap = iosOption.getMap(); aMapFlutterLocation.prepareLoc(androidMap, iosMap); } List
poiList; searchPoi(BMFCoordinate latLng) async { keyWord = textEditingController.text; print("keyWord: ${keyWord}"); var addressPoi = await apiService.searchPoi( "${latLng.latitude}", "${latLng.longitude}", keyWord, 20, 1); List poi = addressPoi['pois']; poiList = poi .map((e) => Address.fromJson({ "address": e["address"] is List ? "" : e["address"], "area": e["adname"], "city": e["cityname"], "province": e["pname"], "latitude": e["location"].toString().split(",")[0], "longitude": e["location"].toString().split(",")[1], "cityInfo": e["name"], "id": "", "mid": "", "phone": "", "tag": "", "username": "", "isDefault": true, })) .toList(); setState(() {}); // BMFPoiNearbySearch bmfPoiNearbySearch = BMFPoiNearbySearch(); // bmfPoiNearbySearch.onGetPoiNearbySearchResult( // callback: (BMFPoiSearchResult result, BMFSearchErrorCode errorCode) { // // if ((DateTime.now().millisecondsSinceEpoch - time) > 2000) { // result.poiInfoList.map((e) => print("sssssssssss:${e.toMap()}")); // poiList = result.poiInfoList; // print("object112221: ${poiList.length}"); // setState(() { // time = DateTime.now().millisecondsSinceEpoch; // }); // // } // }); // bmfPoiNearbySearch.poiNearbySearch(BMFPoiNearbySearchOption( // keywords: [" "], // tags: ["小区","住宅","地标","建筑"], // radius: 100000, // location: latLng, // pageSize: 20, // pageIndex: 0, // isRadiusLimit: true, // )); } int time = 0; startLocation() async { if (!(await Permission.locationWhenInUse.serviceStatus.isEnabled)) { enableLocation(); return; } if (await Permission.location.isPermanentlyDenied) { requestDialog(); } else if (await Permission.location.isGranted) { // EasyLoading.show(status: S.of(context).zhengzaijiazai); aMapFlutterLocation.startLocation(); Future.delayed(Duration(seconds: 6), () { EasyLoading.dismiss(); }); } else if (await Permission.location.isUndetermined) { await Permission.location.request(); } else { if (Platform.isIOS) { //去设置中心 requestDialog(); } else { await Permission.location.request(); } } } enableLocation() { showCupertinoDialog( context: context, builder: (context) { return RequestPermission( "assets/image/icon_permission_location_bg.webp", S.of(context).nindingweigongnengweikaiqi, S.of(context).weilexiangnintuijianfujindemendianxinxi, S.of(context).dakaidingwei, (result) async { if (result) { final AndroidIntent intent = AndroidIntent( action: 'action_location_source_settings', package: "com.zsw.huixiang"); await intent.launch(); // startLocation(); } }, heightRatioWithWidth: 0.82, ); }, ); } requestDialog() { showCupertinoDialog( context: context, builder: (context) { return RequestPermission( "assets/image/icon_permission_location_bg.webp", S.of(context).nindingweiquanxianweiyunxu, S.of(context).weilexiangnintuijianfujindemendianxinxi, S.of(context).kaiqiquanxian, (result) async { if (result) { await openAppSettings(); if (await Permission.location.isGranted) { startLocation(); } } }, heightRatioWithWidth: 0.82, ); }); } BMFMapController _mapController; BMFCoordinate bmfCoordinate; void onMapCreated(BMFMapController controller) { controller.setMapRegionDidChangeCallback(callback: (status) { BMFMapStatus bmfMapStatus = status; print("status: ${bmfMapStatus.toMap()}"); if (bmfCoordinate != null && bmfCoordinate.longitude == status.targetGeoPt.longitude && bmfCoordinate.latitude == status.targetGeoPt.latitude) { if ((DateTime.now().millisecondsSinceEpoch - time) > 1000) { center = status.targetGeoPt; searchPoi(center); time = DateTime.now().millisecondsSinceEpoch; } } else { bmfCoordinate = status.targetGeoPt; } }); setState(() { _mapController = controller; _mapController.showUserLocation(true); _loadCustomData(); addMarker(); }); } BMFCoordinate latLng; BMFMarker bmfMarker; addMarker() { if (latLng == null) return; if (bmfMarker == null && _mapController != null) { print("map_wid: ${MediaQuery.of(context).size.width}"); print("map_hei: ${MediaQuery.of(context).size.height}"); bmfMarker = BMFMarker( position: latLng, screenPointToLock: BMFPoint( (Platform.isIOS ? MediaQuery.of(context).size.width : window.physicalSize.width) / 2, Platform.isIOS ? MediaQuery.of(context).size.height : window.physicalSize.height / 4), isLockedToScreen: true, centerOffset: BMFPoint(0.5, 0.7), enabled: false, icon: "assets/image/icon_address_location.webp", draggable: false, ); _mapController.addMarker(bmfMarker); } bmfMarker.updateIsLockedToScreen( true, BMFPoint( (Platform.isIOS ? MediaQuery.of(context).size.width : window.physicalSize.width) / 2, (Platform.isIOS ? MediaQuery.of(context).size.height : window.physicalSize.height) / 4)); } saveLatLng(BMFCoordinate latLng) async { SharedPreferences prefs = await SharedPreferences.getInstance(); await prefs.setString("latitude", "${latLng.latitude}"); await prefs.setString("longitude", "${latLng.longitude}"); } getLatLng() async { SharedPreferences.getInstance().then((value) => { setState(() { if (_mapController != null) { _mapController.updateMapOptions( BMFMapOptions( center: BMFCoordinate( double.tryParse(value.getString("latitude")), double.tryParse(value.getString("longitude")), ), zoomLevel: 15, ), ); } }) }); } BMFMapWidget map; BMFCoordinate center = BMFCoordinate(30.553111, 114.342366); @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded( child: Stack( children: [ Container( child: BMFMapWidget( mapOptions: BMFMapOptions( center: BMFCoordinate(30.553111, 114.342366), zoomLevel: 12, ), onBMFMapCreated: onMapCreated, // onCameraMoveEnd: (cameraPosition) { // center = cameraPosition.target; // searchPoi(center); // }, // onCameraMove: (cameraPosition) { // center = cameraPosition.target; // setState(() {}); // }, // markers: [Marker(position: center)].toSet(), // touchPoiEnabled: true, // scrollGesturesEnabled: true, // customStyleOptions: _customStyleOptions, // gestureRecognizers: >[ // Factory( // () => EagerGestureRecognizer()) // ].toSet(), ), ), // Center( // child: IgnorePointer( // child: Container( // margin: EdgeInsets.only(bottom: 44.h), // child: Image.asset( // "assets/image/icon_address_location.webp", // width: 66.w, // height: 75.h, // ), // ), // ), // ), searchWidget(), Positioned( right: 17, bottom: 16, child: InkWell( onTap: () { startLocation(); }, child: Container( width: 32, height: 32, padding: EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(16), color: Colors.white, ), child: Image.asset( "assets/image/icon_address_location_action.webp", width: 16.w, height: 16.h, ), ), ), ) ], ), flex: 1, ), Expanded( child: Container( child: ListView.separated( padding: EdgeInsets.symmetric(vertical: 0), itemCount: poiList != null ? poiList.length : 0, itemBuilder: (context, position) { return InkWell( onTap: () { Navigator.of(context).pop(poiList[position].toJson()); }, child: addressItem(poiList[position]), ); }, separatorBuilder: (contetx, position) { return Container( height: 1, margin: EdgeInsets.symmetric(horizontal: 16.w), color: Color(0xFFF1F1F1), ); }, ), ), flex: 1, ) ], ), ); } Widget addressItem(Address address) { return Container( margin: EdgeInsets.symmetric(vertical: 16.h, horizontal: 16.w), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( address.cityInfo ?? "", overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.bold, color: Colors.black, ), ), SizedBox( height: 4.h, ), Text( "${address.province}${address.city}${address.area}${address.address}", overflow: TextOverflow.ellipsis, style: TextStyle( color: Color(0xFF4C4C4C), fontSize: 14.sp, ), ), ], ), ); } TextEditingController textEditingController = TextEditingController(); Widget searchWidget() { return Container( height: 36.h, margin: EdgeInsets.fromLTRB(16, 48, 16, 8), padding: EdgeInsets.fromLTRB(10, 6, 16, 6), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(4)), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(12), offset: Offset(0, 3), blurRadius: 14, spreadRadius: 0, ) ], ), child: Row( mainAxisSize: MainAxisSize.max, children: [ Icon( Icons.search, size: 24, color: Colors.black, ), Expanded( child: TextField( controller: textEditingController, textInputAction: TextInputAction.search, onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); searchPoi(center); }, decoration: InputDecoration(border: InputBorder.none), ), ), InkWell( onTap: () { textEditingController.clear(); }, child: Icon( Icons.close, size: 19, color: Colors.grey, ), ), ], ), ); } }