release: 1.0.10

This commit is contained in:
Kuloud 2024-08-25 22:35:31 +08:00
parent 9c1509c59d
commit 2a889ebbdf
19 changed files with 172 additions and 530 deletions

View File

@ -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、英文状态只在标准地图生效

View File

@ -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(),

View File

@ -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(),
)),
], ],
), ),
); );

View File

@ -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');
}
}

View File

@ -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');
} }
} }

View File

@ -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',
),
],
),
);
}
}

View File

@ -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

View File

@ -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';

View File

@ -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);
}
} }

View File

@ -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);
}
}

View File

@ -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);
});
} }
} }

View File

@ -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') ??
'';
}
} }

View File

@ -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}';
}
}

View File

@ -1 +0,0 @@
export 'buildin/info_window_extension.dart';

View File

@ -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)));
}

View File

@ -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,
}

View File

@ -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);
}

View File

@ -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';

View File

@ -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: