高德地图的Flutter官方插件:amap_flutter_map 3.0,功能不是非常全,我们常用的一个场景,地图在初始化后,将当前位置设为地图显示的中心,在原生的地图SDK上只需要设置地图的一个属性就可以,但是amap_flutter_map并不支持,需要自己实现。
AMapWidget有一个属性initialCameraPosition,是用来指定地图的初始中心位置的。从源代码可以看出,如果initialCameraPosition没有指定的话,默认值是北京市。如果使用定位功能取得当前位置后再初始化地图的话,因为取当前位置需要时间较长,界面会出现长时间的空白。如果地图先显示出来,取得当前位置后再用setState的方式更新initialCameraPosition属性的话,地图没有反应。在initialCameraPosition属性上作文章是没有办法了。
最后用AMapController的moveCamera方法实现了这个功能,但是有一个问题,就是定位需要较长时间,所以在地图显示一段时间后,中心点才移动到当前位置。在将定位精度降低后,在虚拟机上定位时间也没有缩短,现在只能将就用了,希望在真机上定位时间短一些。
下面是相关代码:
import 'dart:async';
import 'package:amap_flutter_base/amap_flutter_base.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:amap_flutter_map/amap_flutter_map.dart';
import 'package:amap_flutter_map_example/base_page.dart';
import 'package:amap_flutter_map_example/const_config.dart';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
class MapPage extends BasePage {
MapPage(String title, String subTitle) : super(title, subTitle);
@override
Widget build(BuildContext context) => _Body();
}
class _Body extends StatefulWidget {
_Body({Key key}) : super(key: key);
@override
_BodyState createState() => _BodyState();
}
class _BodyState extends State<_Body> {
//在按关键字搜索时,传入城市名可以提高搜索精度。
String _cityName;
AMapController _mapController;
Marker _mapMarker;
Map<String, Object> _locationResult;
StreamSubscription<Map<String, Object>> _locationListener;
AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
@override
void initState() {
super.initState();
_requestLocaitonPermission();
AMapFlutterLocation.updatePrivacyShow(true, true);
AMapFlutterLocation.updatePrivacyAgree(true);
AMapFlutterLocation.setApiKey("anroid ApiKey", "a6b2356c68aac3fdabd7ecdce63c2130");
_locationListener = _locationPlugin.onLocationChanged().listen((Map<String, Object> result) {
setState(() {
_locationResult = result;
if (_locationResult != null) {
_cityName = _locationResult['city'];
double longitude = double.tryParse(_locationResult['longitude']);
double latitude = double.tryParse(_locationResult['latitude']);
print('当前位置:longitude:$longitude,latitude:$latitude');
_changeCameraPosition(LatLng(latitude, longitude));
}
});
});
/*
WidgetsBinding.instance.addPostFrameCallback((_) {
_startLocation();
});
*/
_startLocation();
}
///设置定位参数
void _setLocationOption() {
if (null != _locationPlugin) {
AMapLocationOption locationOption = new AMapLocationOption();
locationOption.onceLocation = true;
///是否需要返回逆地理信息
locationOption.needAddress = true;
locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.FullAndReduceAccuracy;
_locationPlugin.setLocationOption(locationOption);
}
}
///开始定位
void _startLocation() {
if (null != _locationPlugin) {
_setLocationOption();
_locationPlugin.startLocation();
}
}
void _requestLocaitonPermission() async {
PermissionStatus status = await Permission.location.request();
print('permissionStatus=====> $status');
}
@override
Widget build(BuildContext context) {
Set<Marker> markers = Set<Marker>();
if (_mapMarker != null) {
markers.add(_mapMarker);
}
AMapWidget aMapWidget = AMapWidget(
privacyStatement: ConstConfig.amapPrivacyStatement,
apiKey: ConstConfig.amapApiKeys,
myLocationStyleOptions: MyLocationStyleOptions(
true,
circleFillColor: Colors.lightBlue,
circleStrokeColor: Colors.blue,
circleStrokeWidth: 1,
),
markers: markers,
compassEnabled: true,
onMapCreated: _onMapCreated,
onCameraMoveEnd: (cameraPosition) {
LatLng markerPosition = cameraPosition.target;
print('=========CameraPosition : ${markerPosition.latitude}');
Marker marker = Marker(position: markerPosition, icon: BitmapDescriptor.fromIconPath('assets/start.png'));
setState(() {
_mapMarker = marker;
});
},
);
return Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
height: MediaQuery.of(context).size.height * 0.6,
width: MediaQuery.of(context).size.width,
child: aMapWidget,
),
Expanded(
child: SingleChildScrollView(
child: Container(
child: SizedBox.shrink(),
),
),
),
],
),
);
}
void _onMapCreated(AMapController controller) {
setState(() {
_mapController = controller;
});
}
void _changeCameraPosition(LatLng position) {
_mapController?.moveCamera(
CameraUpdate.newCameraPosition(
CameraPosition(target: position, zoom: 15),
),
animated: true,
);
}
}