release: 1.0.10
This commit is contained in:
parent
9c1509c59d
commit
2a889ebbdf
|
@ -1,3 +1,9 @@
|
||||||
|
## 1.0.10
|
||||||
|
2024-08-25
|
||||||
|
* 移除extension实现机制
|
||||||
|
* 添加 getMapContentApprovalNumber / getSatelliteImageApprovalNumber(参见example#ShowMapPage)
|
||||||
|
* 添加 InfoWindowAdapter(参见example#CustomInfoWindowDemoPage),结合 infoWindowEnable 和 BaseInfoWindowAdapter 自行实现具体逻辑
|
||||||
|
|
||||||
## 1.0.9
|
## 1.0.9
|
||||||
2024-08-24
|
2024-08-24
|
||||||
* 设置地图语言,支持中文、英文(按SDK描述:1、不能和自定义地图样式同时使用;2、英文状态只在标准地图生效)
|
* 设置地图语言,支持中文、英文(按SDK描述:1、不能和自定义地图样式同时使用;2、英文状态只在标准地图生效)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import 'package:amap_map_example/pages/interactive/map_ui_options.dart';
|
||||||
import 'package:amap_map_example/pages/map/change_map_lang.dart';
|
import 'package:amap_map_example/pages/map/change_map_lang.dart';
|
||||||
import 'package:amap_map_example/pages/map/limit_map_bounds.dart';
|
import 'package:amap_map_example/pages/map/limit_map_bounds.dart';
|
||||||
import 'package:amap_map_example/pages/map/map_my_location.dart';
|
import 'package:amap_map_example/pages/map/map_my_location.dart';
|
||||||
import 'package:amap_map_example/pages/map/map_with_extension_page.dart';
|
|
||||||
import 'package:amap_map_example/pages/map/show_map_page.dart';
|
import 'package:amap_map_example/pages/map/show_map_page.dart';
|
||||||
import 'package:amap_map_example/pages/overlays/custom_info_window.dart';
|
import 'package:amap_map_example/pages/overlays/custom_info_window.dart';
|
||||||
import 'package:amap_map_example/pages/overlays/marker_config.dart';
|
import 'package:amap_map_example/pages/overlays/marker_config.dart';
|
||||||
|
@ -19,8 +18,7 @@ class DemoConfiguration {
|
||||||
final WidgetBuilder buildRoute;
|
final WidgetBuilder buildRoute;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Demo> allDemos() =>
|
List<Demo> allDemos() => mapDemos() + interactiveDemos() + overlayDemos();
|
||||||
mapDemos() + interactiveDemos() + overlayDemos() + extensionDemos();
|
|
||||||
|
|
||||||
List<Demo> mapDemos() {
|
List<Demo> mapDemos() {
|
||||||
return [
|
return [
|
||||||
|
@ -93,19 +91,6 @@ List<Demo> overlayDemos() {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Demo> extensionDemos() {
|
|
||||||
return [
|
|
||||||
Demo(
|
|
||||||
title: '辅助信息获取',
|
|
||||||
category: DemoCategory.extension,
|
|
||||||
subtitle: '获取审图号',
|
|
||||||
slug: 'extension-info',
|
|
||||||
configurations: [
|
|
||||||
DemoConfiguration(buildRoute: (context) => MapWithExtensionPage())
|
|
||||||
])
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String?, Demo> slugToDemo(BuildContext context) {
|
Map<String?, Demo> slugToDemo(BuildContext context) {
|
||||||
return LinkedHashMap<String?, Demo>.fromIterable(
|
return LinkedHashMap<String?, Demo>.fromIterable(
|
||||||
allDemos(),
|
allDemos(),
|
||||||
|
|
|
@ -79,13 +79,6 @@ class _AMapDemoState extends State<AMapDemo>
|
||||||
category: DemoCategory.overlay,
|
category: DemoCategory.overlay,
|
||||||
demos: overlayDemos(),
|
demos: overlayDemos(),
|
||||||
)),
|
)),
|
||||||
AnimatedCategoryItem(
|
|
||||||
startDelayFraction: 0.15,
|
|
||||||
controller: _animationController,
|
|
||||||
child: CategoryListItem(
|
|
||||||
category: DemoCategory.extension,
|
|
||||||
demos: extensionDemos(),
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
// Copyright 2023-2024 kuloud
|
|
||||||
// Copyright 2020 lbs.amap.com
|
|
||||||
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
|
|
||||||
// import 'package:amap_map_extensions/amap_map_extensions.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import 'package:amap_map/amap_map.dart';
|
|
||||||
|
|
||||||
class MapWithExtensionPage extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _MapWithExtensionPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _MapWithExtensionPageState extends State<MapWithExtensionPage> {
|
|
||||||
List<Widget> _approvalNumberWidget = <Widget>[];
|
|
||||||
// final _extension = AmapMapExtensions();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final AMapWidget map = AMapWidget(
|
|
||||||
onMapCreated: onMapCreated,
|
|
||||||
// extensions: [_extension],
|
|
||||||
);
|
|
||||||
|
|
||||||
return ConstrainedBox(
|
|
||||||
constraints: BoxConstraints.expand(),
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: MediaQuery.of(context).size.height,
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
child: map,
|
|
||||||
),
|
|
||||||
Positioned(
|
|
||||||
right: 10,
|
|
||||||
bottom: 15,
|
|
||||||
child: Container(
|
|
||||||
alignment: Alignment.centerLeft,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
children: _approvalNumberWidget),
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
late AMapController _mapController;
|
|
||||||
void onMapCreated(AMapController controller) {
|
|
||||||
setState(() {
|
|
||||||
_mapController = controller;
|
|
||||||
getApprovalNumber();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 获取审图号
|
|
||||||
void getApprovalNumber() async {
|
|
||||||
// //普通地图审图号
|
|
||||||
// String mapContentApprovalNumber =
|
|
||||||
// (await _extension.getMapContentApprovalNumber())!;
|
|
||||||
// //卫星地图审图号
|
|
||||||
// String satelliteImageApprovalNumber =
|
|
||||||
// (await _extension.getSatelliteImageApprovalNumber())!;
|
|
||||||
// setState(() {
|
|
||||||
// _approvalNumberWidget.add(Text(mapContentApprovalNumber));
|
|
||||||
// _approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
|
|
||||||
// });
|
|
||||||
// print('地图审图号(普通地图): $mapContentApprovalNumber');
|
|
||||||
// print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -43,23 +43,23 @@ class _ShowMapPageState extends State<ShowMapPage> {
|
||||||
void onMapCreated(AMapController controller) {
|
void onMapCreated(AMapController controller) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_mapController = controller;
|
_mapController = controller;
|
||||||
// getApprovalNumber();
|
getApprovalNumber();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取审图号
|
/// 获取审图号
|
||||||
void getApprovalNumber() async {
|
void getApprovalNumber() async {
|
||||||
// //普通地图审图号
|
//普通地图审图号
|
||||||
// String mapContentApprovalNumber =
|
String mapContentApprovalNumber =
|
||||||
// (await _mapController.getMapContentApprovalNumber())!;
|
(await _mapController.getMapContentApprovalNumber());
|
||||||
// //卫星地图审图号
|
//卫星地图审图号
|
||||||
// String satelliteImageApprovalNumber =
|
String satelliteImageApprovalNumber =
|
||||||
// (await _mapController.getSatelliteImageApprovalNumber())!;
|
(await _mapController.getSatelliteImageApprovalNumber());
|
||||||
// setState(() {
|
setState(() {
|
||||||
// _approvalNumberWidget.add(Text(mapContentApprovalNumber));
|
_approvalNumberWidget.add(Text(mapContentApprovalNumber));
|
||||||
// _approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
|
_approvalNumberWidget.add(Text(satelliteImageApprovalNumber));
|
||||||
// });
|
});
|
||||||
// print('地图审图号(普通地图): $mapContentApprovalNumber');
|
print('地图审图号(普通地图): $mapContentApprovalNumber');
|
||||||
// print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
print('地图审图号(卫星地图): $satelliteImageApprovalNumber');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,16 +22,13 @@ class _State extends State<CustomInfoWindowDemoPage> {
|
||||||
BitmapDescriptor? _markerIcon;
|
BitmapDescriptor? _markerIcon;
|
||||||
String? selectedMarkerId;
|
String? selectedMarkerId;
|
||||||
bool showInfoWindow = false;
|
bool showInfoWindow = false;
|
||||||
|
AMapController? _controller;
|
||||||
|
|
||||||
final _infoWindowExtension = InfoWindowExtension(
|
Future<void> _onMapCreated(AMapController controller) async {
|
||||||
infoWindow: Container(
|
setState(() {
|
||||||
color: Colors.lightBlue.shade400,
|
_controller = controller;
|
||||||
child: Text('info'),
|
});
|
||||||
),
|
}
|
||||||
option: InfoWindowOption(
|
|
||||||
latLng: mapCenter, offset: EdgeInsets.only(bottom: 32)));
|
|
||||||
|
|
||||||
Future<void> _onMapCreated(AMapController controller) async {}
|
|
||||||
|
|
||||||
void _add() {
|
void _add() {
|
||||||
final int markerCount = _markers.length;
|
final int markerCount = _markers.length;
|
||||||
|
@ -168,8 +165,8 @@ class _State extends State<CustomInfoWindowDemoPage> {
|
||||||
setState(() {
|
setState(() {
|
||||||
showInfoWindow = value;
|
showInfoWindow = value;
|
||||||
_markers[selectedMarkerId!] = marker.copyWith(
|
_markers[selectedMarkerId!] = marker.copyWith(
|
||||||
// visibleParam: value,
|
visibleParam: value,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,14 +187,10 @@ class _State extends State<CustomInfoWindowDemoPage> {
|
||||||
_markerIcon = BitmapDescriptor.fromIconPath('assets/location_marker.png');
|
_markerIcon = BitmapDescriptor.fromIconPath('assets/location_marker.png');
|
||||||
}
|
}
|
||||||
|
|
||||||
_infoWindowExtension.option?.show =
|
AMapWidget map = AMapWidget(
|
||||||
_markers[selectedMarkerId] != null && showInfoWindow;
|
|
||||||
_infoWindowExtension.option?.latLng = _markers[selectedMarkerId]?.position;
|
|
||||||
|
|
||||||
final AMapWidget map = AMapWidget(
|
|
||||||
onMapCreated: _onMapCreated,
|
onMapCreated: _onMapCreated,
|
||||||
markers: Set<Marker>.of(_markers.values),
|
markers: Set<Marker>.of(_markers.values),
|
||||||
extensions: [_infoWindowExtension],
|
infoWindowAdapter: CustomInfoWindowAdapter(_controller, selectedMarkerId),
|
||||||
);
|
);
|
||||||
return Container(
|
return Container(
|
||||||
height: MediaQuery.of(context).size.height,
|
height: MediaQuery.of(context).size.height,
|
||||||
|
@ -293,3 +286,43 @@ class _State extends State<CustomInfoWindowDemoPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CustomInfoWindowAdapter extends BaseInfoWindowAdapter {
|
||||||
|
CustomInfoWindowAdapter(AMapController? controller, this.selectedMarkerId)
|
||||||
|
: super(controller);
|
||||||
|
|
||||||
|
final String? selectedMarkerId;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget? buildInfoWindowContent(BuildContext context, Marker marker) {
|
||||||
|
if (marker.id != selectedMarkerId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(16.0),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: Colors.white,
|
||||||
|
borderRadius: BorderRadius.circular(8.0),
|
||||||
|
boxShadow: [
|
||||||
|
BoxShadow(
|
||||||
|
color: Colors.black26,
|
||||||
|
blurRadius: 4.0,
|
||||||
|
spreadRadius: 2.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
marker.infoWindow.title ?? 'No Title',
|
||||||
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
marker.infoWindow.snippet ?? 'No Snippet',
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ description: Demonstrates how to use the amap_map plugin.
|
||||||
|
|
||||||
# The following line prevents the package from being accidentally published to
|
# The following line prevents the package from being accidentally published to
|
||||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.1.5 <4.0.0"
|
sdk: ">=3.1.5 <4.0.0"
|
||||||
|
@ -16,20 +16,10 @@ dependencies:
|
||||||
flutter_plugin_android_lifecycle: ^2.0.21
|
flutter_plugin_android_lifecycle: ^2.0.21
|
||||||
|
|
||||||
amap_map:
|
amap_map:
|
||||||
# When depending on this package from a real application you should use:
|
|
||||||
# amap_map: ^x.y.z
|
|
||||||
# See https://dart.dev/tools/pub/dependencies#version-constraints
|
|
||||||
# The example app is bundled with the plugin so we use a path dependency on
|
|
||||||
# the parent directory to use the current plugin's version.
|
|
||||||
path: ../
|
path: ../
|
||||||
x_common: ^1.0.4
|
x_common: ^1.0.4
|
||||||
x_amap_base: ^1.0.3
|
x_amap_base: ^1.0.3
|
||||||
|
|
||||||
# amap_map_extensions: ^0.0.1
|
|
||||||
# amap_map_extensions:
|
|
||||||
# path: ../../amap_map_extensions
|
|
||||||
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
@ -39,7 +29,6 @@ dev_dependencies:
|
||||||
|
|
||||||
# The following section is specific to Flutter.
|
# The following section is specific to Flutter.
|
||||||
flutter:
|
flutter:
|
||||||
|
|
||||||
# The following line ensures that the Material Icons font is
|
# The following line ensures that the Material Icons font is
|
||||||
# included with your application, so that you can use the icons in
|
# included with your application, so that you can use the icons in
|
||||||
# the material Icons class.
|
# the material Icons class.
|
||||||
|
@ -51,5 +40,3 @@ flutter:
|
||||||
# assets:
|
# assets:
|
||||||
# - images/a_dot_burr.jpeg
|
# - images/a_dot_burr.jpeg
|
||||||
# - images/a_dot_ham.jpeg
|
# - images/a_dot_ham.jpeg
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -30,5 +30,4 @@ export 'package:amap_map/src/types/types.dart';
|
||||||
part 'src/amap_initializer.dart';
|
part 'src/amap_initializer.dart';
|
||||||
part 'src/amap_controller.dart';
|
part 'src/amap_controller.dart';
|
||||||
part 'src/amap_widget.dart';
|
part 'src/amap_widget.dart';
|
||||||
part 'src/amap_loader.dart';
|
|
||||||
part 'src/utils/location_utils.dart';
|
part 'src/utils/location_utils.dart';
|
||||||
|
|
|
@ -55,43 +55,37 @@ class AMapController {
|
||||||
_methodChannel
|
_methodChannel
|
||||||
.onCameraMove(mapId: mapId)
|
.onCameraMove(mapId: mapId)
|
||||||
.listen((CameraPositionMoveEvent e) {
|
.listen((CameraPositionMoveEvent e) {
|
||||||
_mapState._extensions.values.forEach((ext) => ext.onCameraMove(e.value));
|
|
||||||
_mapState.widget.onCameraMove?.call(e.value);
|
_mapState.widget.onCameraMove?.call(e.value);
|
||||||
|
if (_mapState.widget.infoWindowAdapter != null) {
|
||||||
|
_mapState.updateMarkers();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
_methodChannel
|
_methodChannel
|
||||||
.onCameraMoveEnd(mapId: mapId)
|
.onCameraMoveEnd(mapId: mapId)
|
||||||
.listen((CameraPositionMoveEndEvent e) {
|
.listen((CameraPositionMoveEndEvent e) {
|
||||||
_mapState._extensions.values
|
|
||||||
.forEach((ext) => ext.onCameraMoveEnd(e.value));
|
|
||||||
_mapState.widget.onCameraMoveEnd?.call(e.value);
|
_mapState.widget.onCameraMoveEnd?.call(e.value);
|
||||||
});
|
});
|
||||||
_methodChannel
|
_methodChannel
|
||||||
.onMapTap(mapId: mapId)
|
.onMapTap(mapId: mapId)
|
||||||
.listen(((MapTapEvent e) => _mapState.widget.onTap?.call(e.value)));
|
.listen(((MapTapEvent e) => _mapState.widget.onTap?.call(e.value)));
|
||||||
_methodChannel.onMapLongPress(mapId: mapId).listen(((MapLongPressEvent e) {
|
_methodChannel.onMapLongPress(mapId: mapId).listen(((MapLongPressEvent e) {
|
||||||
_mapState._extensions.values.forEach((ext) => ext.onLongPress(e.value));
|
|
||||||
_mapState.widget.onLongPress?.call(e.value);
|
_mapState.widget.onLongPress?.call(e.value);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
_methodChannel.onPoiTouched(mapId: mapId).listen(((MapPoiTouchEvent e) {
|
_methodChannel.onPoiTouched(mapId: mapId).listen(((MapPoiTouchEvent e) {
|
||||||
_mapState._extensions.values.forEach((ext) => ext.onPoiTouched(e.value));
|
|
||||||
_mapState.widget.onPoiTouched?.call(e.value);
|
_mapState.widget.onPoiTouched?.call(e.value);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
_methodChannel.onMarkerTap(mapId: mapId).listen((MarkerTapEvent e) {
|
_methodChannel.onMarkerTap(mapId: mapId).listen((MarkerTapEvent e) {
|
||||||
_mapState._extensions.values.forEach((ext) => ext.onMarkerTap(e.value));
|
|
||||||
_mapState.onMarkerTap(e.value);
|
_mapState.onMarkerTap(e.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
_methodChannel.onMarkerDragEnd(mapId: mapId).listen((MarkerDragEndEvent e) {
|
_methodChannel.onMarkerDragEnd(mapId: mapId).listen((MarkerDragEndEvent e) {
|
||||||
_mapState._extensions.values
|
|
||||||
.forEach((ext) => ext.onMarkerDragEnd(e.value));
|
|
||||||
_mapState.onMarkerDragEnd(e.value, e.position);
|
_mapState.onMarkerDragEnd(e.value, e.position);
|
||||||
});
|
});
|
||||||
|
|
||||||
_methodChannel.onPolylineTap(mapId: mapId).listen((PolylineTapEvent e) {
|
_methodChannel.onPolylineTap(mapId: mapId).listen((PolylineTapEvent e) {
|
||||||
_mapState._extensions.values.forEach((ext) => ext.onPolylineTap(e.value));
|
|
||||||
_mapState.onPolylineTap(e.value);
|
_mapState.onPolylineTap(e.value);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -150,4 +144,12 @@ class AMapController {
|
||||||
Future<LatLng> fromScreenCoordinate(ScreenCoordinate screenCoordinate) {
|
Future<LatLng> fromScreenCoordinate(ScreenCoordinate screenCoordinate) {
|
||||||
return _methodChannel.fromScreenLocation(screenCoordinate, mapId: mapId);
|
return _methodChannel.fromScreenLocation(screenCoordinate, mapId: mapId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> getMapContentApprovalNumber() {
|
||||||
|
return _methodChannel.getMapContentApprovalNumber(mapId: mapId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getSatelliteImageApprovalNumber() {
|
||||||
|
return _methodChannel.getSatelliteImageApprovalNumber(mapId: mapId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
// Copyright 2023-2024 kuloud
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
|
|
||||||
part of amap_map;
|
|
||||||
|
|
||||||
/// 加载器,在[AMapWidget]的生命周期上绑定拓展
|
|
||||||
class AMapLoader extends StatefulWidget {
|
|
||||||
const AMapLoader(
|
|
||||||
{super.key, required this.mapView, required this.extensions});
|
|
||||||
|
|
||||||
final Widget mapView;
|
|
||||||
final List<AMapExtension> extensions;
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<AMapLoader> createState() => _AMapLoaderState();
|
|
||||||
|
|
||||||
static void prepare() {
|
|
||||||
// TODO Loader 初始化静态方法,在initState时做些逻辑
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 传递构建视图,拓展按需进行包装和挂载定制视图
|
|
||||||
Widget buildFromExtension(AMapContext aMapContext) {
|
|
||||||
Widget child = mapView;
|
|
||||||
for (var e in extensions) {
|
|
||||||
child = e.build(aMapContext, child);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [didChangeDependencies] 状态更新时,挨个遍历进行拓展的更新操作
|
|
||||||
void prepareFromExtension(AMapContext aMapContext) {
|
|
||||||
for (var e in extensions) {
|
|
||||||
e.prepare(aMapContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [didChangeDependencies] 状态更新时,挨个遍历进行拓展的更新操作
|
|
||||||
void updateFromExtension(AMapContext aMapContext) {
|
|
||||||
for (var e in extensions) {
|
|
||||||
e.update(aMapContext);
|
|
||||||
}
|
|
||||||
// Future.forEach(extensions, (ext) => ext.update(aMapContext));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _AMapLoaderState extends State<AMapLoader> {
|
|
||||||
@override
|
|
||||||
void didChangeDependencies() {
|
|
||||||
final aMapContext = AMapContext(
|
|
||||||
buildContext: context,
|
|
||||||
currentStep: CurrentStep.preparing,
|
|
||||||
loader: widget);
|
|
||||||
|
|
||||||
widget.prepareFromExtension(aMapContext);
|
|
||||||
super.didChangeDependencies();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void didUpdateWidget(covariant AMapLoader oldWidget) {
|
|
||||||
final aMapContext = AMapContext(
|
|
||||||
buildContext: context,
|
|
||||||
currentStep: CurrentStep.updating,
|
|
||||||
loader: widget);
|
|
||||||
widget.updateFromExtension(aMapContext);
|
|
||||||
super.didUpdateWidget(oldWidget);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
for (var e in widget.extensions) {
|
|
||||||
e.onDispose();
|
|
||||||
}
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
// Set the extension context for this node.
|
|
||||||
final aMapContext = AMapContext(
|
|
||||||
buildContext: context,
|
|
||||||
currentStep: CurrentStep.building,
|
|
||||||
loader: widget);
|
|
||||||
|
|
||||||
return widget.buildFromExtension(aMapContext);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -106,11 +106,11 @@ class AMapWidget extends StatefulWidget {
|
||||||
///需要应用到地图上的手势集合
|
///需要应用到地图上的手势集合
|
||||||
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
|
final Set<Factory<OneSequenceGestureRecognizer>> gestureRecognizers;
|
||||||
|
|
||||||
final List<AMapExtension> extensions;
|
|
||||||
|
|
||||||
/// 设置地图语言
|
/// 设置地图语言
|
||||||
final MapLanguage? mapLanguage;
|
final MapLanguage? mapLanguage;
|
||||||
|
|
||||||
|
final InfoWindowAdapter? infoWindowAdapter;
|
||||||
|
|
||||||
/// 创建一个展示高德地图的widget
|
/// 创建一个展示高德地图的widget
|
||||||
///
|
///
|
||||||
/// 在app首次启动时必须传入高德合规声明配置[privacyStatement],后续如果没有变化不需要重复设置
|
/// 在app首次启动时必须传入高德合规声明配置[privacyStatement],后续如果没有变化不需要重复设置
|
||||||
|
@ -152,8 +152,8 @@ class AMapWidget extends StatefulWidget {
|
||||||
this.markers = const <Marker>{},
|
this.markers = const <Marker>{},
|
||||||
this.polylines = const <Polyline>{},
|
this.polylines = const <Polyline>{},
|
||||||
this.polygons = const <Polygon>{},
|
this.polygons = const <Polygon>{},
|
||||||
this.extensions = const [],
|
|
||||||
this.mapLanguage,
|
this.mapLanguage,
|
||||||
|
this.infoWindowAdapter,
|
||||||
this.logoPosition,
|
this.logoPosition,
|
||||||
this.logoBottomMargin,
|
this.logoBottomMargin,
|
||||||
this.logoLeftMargin})
|
this.logoLeftMargin})
|
||||||
|
@ -168,7 +168,7 @@ class _MapState extends State<AMapWidget> {
|
||||||
Map<String, Marker> _markers = <String, Marker>{};
|
Map<String, Marker> _markers = <String, Marker>{};
|
||||||
Map<String, Polyline> _polylines = <String, Polyline>{};
|
Map<String, Polyline> _polylines = <String, Polyline>{};
|
||||||
Map<String, Polygon> _polygons = <String, Polygon>{};
|
Map<String, Polygon> _polygons = <String, Polygon>{};
|
||||||
Map<String, AMapExtension> _extensions = <String, AMapExtension>{};
|
Map<String, Widget?> _infoWindows = <String, Widget?>{};
|
||||||
|
|
||||||
final Completer<AMapController> _controller = Completer<AMapController>();
|
final Completer<AMapController> _controller = Completer<AMapController>();
|
||||||
late _AMapOptions _mapOptions;
|
late _AMapOptions _mapOptions;
|
||||||
|
@ -190,22 +190,19 @@ class _MapState extends State<AMapWidget> {
|
||||||
onPlatformViewCreated,
|
onPlatformViewCreated,
|
||||||
);
|
);
|
||||||
|
|
||||||
return AMapLoader(
|
return Stack(
|
||||||
mapView: mapView,
|
children: [mapView, ..._infoWindows.values.nonNulls],
|
||||||
extensions: widget.extensions,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
AMapLoader.prepare();
|
|
||||||
super.initState();
|
super.initState();
|
||||||
_mapOptions = _AMapOptions.fromWidget(widget);
|
_mapOptions = _AMapOptions.fromWidget(widget);
|
||||||
_markers = keyByMarkerId(widget.markers);
|
_markers = keyByMarkerId(widget.markers);
|
||||||
_polygons = keyByPolygonId(widget.polygons);
|
_polygons = keyByPolygonId(widget.polygons);
|
||||||
_polylines = keyByPolylineId(widget.polylines);
|
_polylines = keyByPolylineId(widget.polylines);
|
||||||
|
|
||||||
_extensions = keyByExtensionId(widget.extensions);
|
|
||||||
print('initState AMapWidget');
|
print('initState AMapWidget');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,10 +230,9 @@ class _MapState extends State<AMapWidget> {
|
||||||
void didUpdateWidget(covariant AMapWidget oldWidget) {
|
void didUpdateWidget(covariant AMapWidget oldWidget) {
|
||||||
super.didUpdateWidget(oldWidget);
|
super.didUpdateWidget(oldWidget);
|
||||||
_updateOptions();
|
_updateOptions();
|
||||||
_updateMarkers();
|
updateMarkers();
|
||||||
_updatePolylines();
|
_updatePolylines();
|
||||||
_updatePolygons();
|
_updatePolygons();
|
||||||
_updateExtensions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> onPlatformViewCreated(int id) async {
|
Future<void> onPlatformViewCreated(int id) async {
|
||||||
|
@ -247,14 +243,6 @@ class _MapState extends State<AMapWidget> {
|
||||||
);
|
);
|
||||||
_controller.complete(controller);
|
_controller.complete(controller);
|
||||||
|
|
||||||
if (_extensions.isNotEmpty) {
|
|
||||||
debugPrint('[onPlatformViewCreated] $controller');
|
|
||||||
await Future.forEach(_extensions.values, (e) {
|
|
||||||
e.bindMethodChannel(controller.channel);
|
|
||||||
e.bindMapController(controller);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
final MapCreatedCallback? _onMapCreated = widget.onMapCreated;
|
final MapCreatedCallback? _onMapCreated = widget.onMapCreated;
|
||||||
if (_onMapCreated != null) {
|
if (_onMapCreated != null) {
|
||||||
_onMapCreated(controller);
|
_onMapCreated(controller);
|
||||||
|
@ -303,12 +291,24 @@ class _MapState extends State<AMapWidget> {
|
||||||
_mapOptions = newOptions;
|
_mapOptions = newOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateMarkers() async {
|
void updateMarkers() async {
|
||||||
final AMapController controller = await _controller.future;
|
final AMapController controller = await _controller.future;
|
||||||
|
MarkerUpdates markerUpdates =
|
||||||
|
MarkerUpdates.from(_markers.values.toSet(), widget.markers);
|
||||||
|
|
||||||
|
markerUpdates.markerIdsToRemove?.forEach((markerId) {
|
||||||
|
_removeInfoWindow(markerId);
|
||||||
|
});
|
||||||
|
|
||||||
// ignore: unawaited_futures
|
// ignore: unawaited_futures
|
||||||
controller._updateMarkers(
|
controller._updateMarkers(markerUpdates);
|
||||||
MarkerUpdates.from(_markers.values.toSet(), widget.markers));
|
|
||||||
_markers = keyByMarkerId(widget.markers);
|
_markers = keyByMarkerId(widget.markers);
|
||||||
|
|
||||||
|
if (widget.infoWindowAdapter != null) {
|
||||||
|
_markers.values.forEach((marker) {
|
||||||
|
_onInfoWindowUpdate(marker);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updatePolylines() async {
|
void _updatePolylines() async {
|
||||||
|
@ -325,9 +325,19 @@ class _MapState extends State<AMapWidget> {
|
||||||
_polygons = keyByPolygonId(widget.polygons);
|
_polygons = keyByPolygonId(widget.polygons);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateExtensions() async {
|
void _onInfoWindowUpdate(Marker marker) {
|
||||||
// final AMapController controller = await _controller.future;
|
if (widget.infoWindowAdapter != null) {
|
||||||
_extensions = keyByExtensionId(widget.extensions);
|
setState(() {
|
||||||
|
_infoWindows[marker.id] =
|
||||||
|
widget.infoWindowAdapter!.getInfoWindow(context, marker);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeInfoWindow(String markerId) {
|
||||||
|
setState(() {
|
||||||
|
_infoWindows.remove(markerId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -284,4 +284,20 @@ class MethodChannelAMapFlutterMap implements AMapFlutterPlatform {
|
||||||
'map#fromScreenCoordinate', screenCoordinate.toJson());
|
'map#fromScreenCoordinate', screenCoordinate.toJson());
|
||||||
return LatLng(latLng![0] as double, latLng[1] as double);
|
return LatLng(latLng![0] as double, latLng[1] as double);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> getMapContentApprovalNumber({
|
||||||
|
required int mapId,
|
||||||
|
}) async {
|
||||||
|
return await channel(mapId)
|
||||||
|
.invokeMethod<String>('map#contentApprovalNumber') ??
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<String> getSatelliteImageApprovalNumber({
|
||||||
|
required int mapId,
|
||||||
|
}) async {
|
||||||
|
return await channel(mapId)
|
||||||
|
.invokeMethod<String>('map#satelliteImageApprovalNumber') ??
|
||||||
|
'';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
import 'dart:async';
|
|
||||||
|
|
||||||
import 'package:amap_map/amap_map.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:x_amap_base/x_amap_base.dart';
|
|
||||||
|
|
||||||
/// [amap_map]插件支持默认的[InfoWindow]展示[title]和[snippet]字段,如果要自定义
|
|
||||||
/// [InfoWindow],需要集成此内置插件。
|
|
||||||
///
|
|
||||||
/// ```dart
|
|
||||||
/// AMapWidget map = AMapWidget(
|
|
||||||
/// onMapCreated: _onMapCreated,
|
|
||||||
/// markers: Set<Marker>.of(_markers.values),
|
|
||||||
/// extensions: [
|
|
||||||
/// InfoWindowExtension(
|
|
||||||
/// infoWindow: Container(
|
|
||||||
/// child: Text('Custom widget'),
|
|
||||||
/// ))
|
|
||||||
/// ],
|
|
||||||
/// )
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// 此插件会在[AMapWidget]外侧套一层[Stack],根据屏幕坐标和经纬度进行适配自定义视图
|
|
||||||
///
|
|
||||||
/// ```dart
|
|
||||||
/// Stack(
|
|
||||||
/// children: [
|
|
||||||
/// child,
|
|
||||||
/// Positioned(
|
|
||||||
/// top: 0,
|
|
||||||
/// left: 0,
|
|
||||||
/// child: Visibility(child: infoWindow),
|
|
||||||
/// ),
|
|
||||||
/// ],
|
|
||||||
/// )
|
|
||||||
/// ```
|
|
||||||
class InfoWindowExtension extends AMapExtension {
|
|
||||||
InfoWindowExtension({required this.infoWindow, this.option});
|
|
||||||
|
|
||||||
final _streamController = StreamController<InfoWindowExtension>.broadcast();
|
|
||||||
|
|
||||||
final Widget infoWindow;
|
|
||||||
InfoWindowOption? option;
|
|
||||||
|
|
||||||
final GlobalKey _infoWindowKey = GlobalKey();
|
|
||||||
|
|
||||||
AMapController? mapController;
|
|
||||||
double? _x;
|
|
||||||
double? _y;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void update(AMapContext aMapContext) {
|
|
||||||
_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
onCameraMove(CameraPosition value) {
|
|
||||||
_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
_update() async {
|
|
||||||
if (mapController == null || option?.latLng == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final coordinate = await mapController!.toScreenCoordinate(option!.latLng!);
|
|
||||||
|
|
||||||
_x = coordinate.x.toDouble();
|
|
||||||
_y = coordinate.y.toDouble();
|
|
||||||
|
|
||||||
final size = _infoWindowKey.currentContext?.size;
|
|
||||||
if (size != null && _x != null && _y != null) {
|
|
||||||
_x = _x! - size.width / 2;
|
|
||||||
_y = _y! - size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
_streamController.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bindMapController(AMapController controller) {
|
|
||||||
debugPrint('[InfoWindowExtension] bindMapController: $controller');
|
|
||||||
mapController = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(AMapContext aMapContext, Widget child) {
|
|
||||||
return Stack(
|
|
||||||
key: ValueKey(this),
|
|
||||||
children: [
|
|
||||||
child,
|
|
||||||
StreamBuilder<InfoWindowExtension>(
|
|
||||||
initialData: this,
|
|
||||||
stream: _streamController.stream,
|
|
||||||
builder: (context, snapshot) {
|
|
||||||
final data = snapshot.data;
|
|
||||||
if (data == null ||
|
|
||||||
!(data.option?.show ?? false) ||
|
|
||||||
data._x == null) {
|
|
||||||
return Container();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Positioned(
|
|
||||||
top: data._y,
|
|
||||||
left: data._x,
|
|
||||||
child: Container(
|
|
||||||
key: _infoWindowKey,
|
|
||||||
margin: data.option?.offset,
|
|
||||||
child: infoWindow,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onDispose() {
|
|
||||||
_streamController.close();
|
|
||||||
super.onDispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class InfoWindowOption {
|
|
||||||
bool show = false;
|
|
||||||
LatLng? latLng;
|
|
||||||
EdgeInsetsGeometry? offset;
|
|
||||||
|
|
||||||
InfoWindowOption({this.show = false, this.latLng, this.offset});
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() {
|
|
||||||
return 'InfoWindowOption{show: $show, latLng: $latLng, offset: $offset}';
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
export 'buildin/info_window_extension.dart';
|
|
|
@ -1,81 +0,0 @@
|
||||||
// Copyright 2023-2024 kuloud
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
|
|
||||||
import 'package:amap_map/amap_map.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:x_amap_base/x_amap_base.dart';
|
|
||||||
|
|
||||||
/// 插件拓展,绑定[AMapWidget]的生命周期和控制器,实现基于地图的拓展能力(通常是地图交互的可
|
|
||||||
/// 选功能)
|
|
||||||
abstract class AMapExtension {
|
|
||||||
late String _id;
|
|
||||||
|
|
||||||
String get id => _id;
|
|
||||||
|
|
||||||
AMapExtension() {
|
|
||||||
this._id = this.hashCode.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 视图层级变化
|
|
||||||
/// since v1.0.4
|
|
||||||
void prepare(AMapContext aMapContext) {}
|
|
||||||
|
|
||||||
/// 视图变化
|
|
||||||
/// since v1.0.4
|
|
||||||
void update(AMapContext aMapContext) {}
|
|
||||||
|
|
||||||
void onDispose() {}
|
|
||||||
|
|
||||||
@Deprecated('使用 bindMapController ,计划在1.0.6移除')
|
|
||||||
bindMethodChannel(MethodChannel channel) {}
|
|
||||||
|
|
||||||
/// 注入[AMapController] 方便地图交互
|
|
||||||
bindMapController(AMapController controller) {}
|
|
||||||
|
|
||||||
Widget build(AMapContext aMapContext, Widget child) {
|
|
||||||
/// 默认传递[AMapWidget],有部分场景需要在[AMapWidget]外包装容器,根据传递拓展列表顺序
|
|
||||||
/// 链式执行
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onCameraMove(CameraPosition cameraPosition) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onCameraMoveEnd(CameraPosition cameraPosition) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onLongPress(LatLng latLng) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onPoiTouched(AMapPoi poi) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onMarkerTap(String value) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onMarkerDragEnd(String value) {}
|
|
||||||
|
|
||||||
/// since v1.0.4
|
|
||||||
onPolylineTap(String value) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, AMapExtension> keyByExtensionId(
|
|
||||||
Iterable<AMapExtension> extensions) {
|
|
||||||
// ignore: unnecessary_null_comparison
|
|
||||||
if (extensions == null) {
|
|
||||||
return <String, AMapExtension>{};
|
|
||||||
}
|
|
||||||
return Map<String, AMapExtension>.fromEntries(extensions.map(
|
|
||||||
(AMapExtension extension) =>
|
|
||||||
MapEntry<String, AMapExtension>(extension.id, extension)));
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright 2023-2024 kuloud
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
// you may not use this file except in compliance with the License.
|
|
||||||
// You may obtain a copy of the License at
|
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
|
|
||||||
import 'package:amap_map/amap_map.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
/// 上下文
|
|
||||||
class AMapContext {
|
|
||||||
final BuildContext buildContext;
|
|
||||||
final CurrentStep currentStep;
|
|
||||||
final AMapLoader loader;
|
|
||||||
|
|
||||||
AMapContext(
|
|
||||||
{required this.buildContext,
|
|
||||||
required this.currentStep,
|
|
||||||
required this.loader});
|
|
||||||
}
|
|
||||||
|
|
||||||
enum CurrentStep {
|
|
||||||
preparing,
|
|
||||||
updating,
|
|
||||||
building,
|
|
||||||
}
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import 'package:amap_map/amap_map.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
abstract class InfoWindowAdapter {
|
||||||
|
Widget? getInfoWindow(BuildContext context, Marker marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class BaseInfoWindowAdapter implements InfoWindowAdapter {
|
||||||
|
final AMapController? controller;
|
||||||
|
|
||||||
|
BaseInfoWindowAdapter(this.controller);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget? getInfoWindow(BuildContext context, Marker marker) {
|
||||||
|
final contentView = buildInfoWindowContent(context, marker);
|
||||||
|
return (contentView != null)
|
||||||
|
? FutureBuilder(
|
||||||
|
future: controller?.toScreenCoordinate(marker.position),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
if (snapshot.hasData) {
|
||||||
|
double devicePixelRatio =
|
||||||
|
MediaQuery.of(context).devicePixelRatio;
|
||||||
|
return Positioned(
|
||||||
|
left: snapshot.data!.x.toDouble() / devicePixelRatio,
|
||||||
|
top: snapshot.data!.y.toDouble() / devicePixelRatio,
|
||||||
|
child: contentView,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return Container(); // 当未获取到数据时,返回空的 `Container`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget? buildInfoWindowContent(BuildContext context, Marker marker);
|
||||||
|
}
|
|
@ -20,8 +20,5 @@ export 'polyline_updates.dart';
|
||||||
export 'polygon.dart';
|
export 'polygon.dart';
|
||||||
export 'polygon_updates.dart';
|
export 'polygon_updates.dart';
|
||||||
export 'bitmap.dart';
|
export 'bitmap.dart';
|
||||||
export 'extension_context.dart';
|
|
||||||
export 'amap_extension.dart';
|
|
||||||
export 'screen_coordinate.dart';
|
export 'screen_coordinate.dart';
|
||||||
|
export 'info_window_adapter.dart';
|
||||||
export '../extension/extensions.dart';
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: amap_map
|
name: amap_map
|
||||||
description: Amap SDK Flutter plugin for integrating AMapSDK in iOS and Android applications.
|
description: Amap SDK Flutter plugin for integrating AMapSDK in iOS and Android applications.
|
||||||
version: 1.0.9
|
version: 1.0.10
|
||||||
homepage: https://github.com/kuloud/amap_map
|
homepage: https://github.com/kuloud/amap_map
|
||||||
issue_tracker: https://github.com/kuloud/amap_map/issues
|
issue_tracker: https://github.com/kuloud/amap_map/issues
|
||||||
platforms:
|
platforms:
|
||||||
|
|
Loading…
Reference in New Issue