From 2a889ebbdf9bb41e55882579f449f006fa6c94f3 Mon Sep 17 00:00:00 2001 From: Kuloud Date: Sun, 25 Aug 2024 22:35:31 +0800 Subject: [PATCH] release: 1.0.10 --- CHANGELOG.md | 6 + example/lib/data/demos.dart | 17 +-- example/lib/main.dart | 7 - .../pages/map/map_with_extension_page.dart | 81 ----------- example/lib/pages/map/show_map_page.dart | 26 ++-- .../pages/overlays/custom_info_window.dart | 67 ++++++--- example/pubspec.yaml | 15 +- lib/amap_map.dart | 1 - lib/src/amap_controller.dart | 20 +-- lib/src/amap_loader.dart | 94 ------------ lib/src/amap_widget.dart | 60 ++++---- lib/src/core/method_channel_amap_map.dart | 16 +++ .../buildin/info_window_extension.dart | 135 ------------------ lib/src/extension/extensions.dart | 1 - lib/src/types/amap_extension.dart | 81 ----------- lib/src/types/extension_context.dart | 31 ---- lib/src/types/info_window_adapter.dart | 37 +++++ lib/src/types/types.dart | 5 +- pubspec.yaml | 2 +- 19 files changed, 172 insertions(+), 530 deletions(-) delete mode 100644 example/lib/pages/map/map_with_extension_page.dart delete mode 100644 lib/src/amap_loader.dart delete mode 100644 lib/src/extension/buildin/info_window_extension.dart delete mode 100644 lib/src/extension/extensions.dart delete mode 100644 lib/src/types/amap_extension.dart delete mode 100644 lib/src/types/extension_context.dart create mode 100644 lib/src/types/info_window_adapter.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index b4d48e2..9bcd124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +## 1.0.10 +2024-08-25 +* 移除extension实现机制 +* 添加 getMapContentApprovalNumber / getSatelliteImageApprovalNumber(参见example#ShowMapPage) +* 添加 InfoWindowAdapter(参见example#CustomInfoWindowDemoPage),结合 infoWindowEnable 和 BaseInfoWindowAdapter 自行实现具体逻辑 + ## 1.0.9 2024-08-24 * 设置地图语言,支持中文、英文(按SDK描述:1、不能和自定义地图样式同时使用;2、英文状态只在标准地图生效) diff --git a/example/lib/data/demos.dart b/example/lib/data/demos.dart index 9ed4b3c..5c78545 100644 --- a/example/lib/data/demos.dart +++ b/example/lib/data/demos.dart @@ -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/limit_map_bounds.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/overlays/custom_info_window.dart'; import 'package:amap_map_example/pages/overlays/marker_config.dart'; @@ -19,8 +18,7 @@ class DemoConfiguration { final WidgetBuilder buildRoute; } -List allDemos() => - mapDemos() + interactiveDemos() + overlayDemos() + extensionDemos(); +List allDemos() => mapDemos() + interactiveDemos() + overlayDemos(); List mapDemos() { return [ @@ -93,19 +91,6 @@ List overlayDemos() { ]; } -List extensionDemos() { - return [ - Demo( - title: '辅助信息获取', - category: DemoCategory.extension, - subtitle: '获取审图号', - slug: 'extension-info', - configurations: [ - DemoConfiguration(buildRoute: (context) => MapWithExtensionPage()) - ]) - ]; -} - Map slugToDemo(BuildContext context) { return LinkedHashMap.fromIterable( allDemos(), diff --git a/example/lib/main.dart b/example/lib/main.dart index d9c5d67..3da3abc 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -79,13 +79,6 @@ class _AMapDemoState extends State category: DemoCategory.overlay, demos: overlayDemos(), )), - AnimatedCategoryItem( - startDelayFraction: 0.15, - controller: _animationController, - child: CategoryListItem( - category: DemoCategory.extension, - demos: extensionDemos(), - )), ], ), ); diff --git a/example/lib/pages/map/map_with_extension_page.dart b/example/lib/pages/map/map_with_extension_page.dart deleted file mode 100644 index 00aad1b..0000000 --- a/example/lib/pages/map/map_with_extension_page.dart +++ /dev/null @@ -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 createState() => _MapWithExtensionPageState(); -} - -class _MapWithExtensionPageState extends State { - List _approvalNumberWidget = []; - // 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'); - } -} diff --git a/example/lib/pages/map/show_map_page.dart b/example/lib/pages/map/show_map_page.dart index 9800a34..025baf0 100644 --- a/example/lib/pages/map/show_map_page.dart +++ b/example/lib/pages/map/show_map_page.dart @@ -43,23 +43,23 @@ class _ShowMapPageState extends State { void onMapCreated(AMapController controller) { setState(() { _mapController = controller; - // getApprovalNumber(); + getApprovalNumber(); }); } /// 获取审图号 void getApprovalNumber() async { - // //普通地图审图号 - // String mapContentApprovalNumber = - // (await _mapController.getMapContentApprovalNumber())!; - // //卫星地图审图号 - // String satelliteImageApprovalNumber = - // (await _mapController.getSatelliteImageApprovalNumber())!; - // setState(() { - // _approvalNumberWidget.add(Text(mapContentApprovalNumber)); - // _approvalNumberWidget.add(Text(satelliteImageApprovalNumber)); - // }); - // print('地图审图号(普通地图): $mapContentApprovalNumber'); - // print('地图审图号(卫星地图): $satelliteImageApprovalNumber'); + //普通地图审图号 + String mapContentApprovalNumber = + (await _mapController.getMapContentApprovalNumber()); + //卫星地图审图号 + String satelliteImageApprovalNumber = + (await _mapController.getSatelliteImageApprovalNumber()); + setState(() { + _approvalNumberWidget.add(Text(mapContentApprovalNumber)); + _approvalNumberWidget.add(Text(satelliteImageApprovalNumber)); + }); + print('地图审图号(普通地图): $mapContentApprovalNumber'); + print('地图审图号(卫星地图): $satelliteImageApprovalNumber'); } } diff --git a/example/lib/pages/overlays/custom_info_window.dart b/example/lib/pages/overlays/custom_info_window.dart index 8f0871d..87d43a4 100644 --- a/example/lib/pages/overlays/custom_info_window.dart +++ b/example/lib/pages/overlays/custom_info_window.dart @@ -22,16 +22,13 @@ class _State extends State { BitmapDescriptor? _markerIcon; String? selectedMarkerId; bool showInfoWindow = false; + AMapController? _controller; - final _infoWindowExtension = InfoWindowExtension( - infoWindow: Container( - color: Colors.lightBlue.shade400, - child: Text('info'), - ), - option: InfoWindowOption( - latLng: mapCenter, offset: EdgeInsets.only(bottom: 32))); - - Future _onMapCreated(AMapController controller) async {} + Future _onMapCreated(AMapController controller) async { + setState(() { + _controller = controller; + }); + } void _add() { final int markerCount = _markers.length; @@ -168,8 +165,8 @@ class _State extends State { setState(() { showInfoWindow = value; _markers[selectedMarkerId!] = marker.copyWith( - // visibleParam: value, - ); + visibleParam: value, + ); }); } @@ -190,14 +187,10 @@ class _State extends State { _markerIcon = BitmapDescriptor.fromIconPath('assets/location_marker.png'); } - _infoWindowExtension.option?.show = - _markers[selectedMarkerId] != null && showInfoWindow; - _infoWindowExtension.option?.latLng = _markers[selectedMarkerId]?.position; - - final AMapWidget map = AMapWidget( + AMapWidget map = AMapWidget( onMapCreated: _onMapCreated, markers: Set.of(_markers.values), - extensions: [_infoWindowExtension], + infoWindowAdapter: CustomInfoWindowAdapter(_controller, selectedMarkerId), ); return Container( height: MediaQuery.of(context).size.height, @@ -293,3 +286,43 @@ class _State extends State { ); } } + +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', + ), + ], + ), + ); + } +} diff --git a/example/pubspec.yaml b/example/pubspec.yaml index bbc1c7f..c3d971a 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -3,7 +3,7 @@ description: Demonstrates how to use the amap_map plugin. # The following line prevents the package from being accidentally published to # 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: sdk: ">=3.1.5 <4.0.0" @@ -16,20 +16,10 @@ dependencies: flutter_plugin_android_lifecycle: ^2.0.21 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: ../ x_common: ^1.0.4 x_amap_base: ^1.0.3 - # amap_map_extensions: ^0.0.1 - # amap_map_extensions: - # path: ../../amap_map_extensions - - dev_dependencies: flutter_test: sdk: flutter @@ -39,7 +29,6 @@ dev_dependencies: # The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -51,5 +40,3 @@ flutter: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg - - diff --git a/lib/amap_map.dart b/lib/amap_map.dart index 927a673..d6b74c3 100644 --- a/lib/amap_map.dart +++ b/lib/amap_map.dart @@ -30,5 +30,4 @@ export 'package:amap_map/src/types/types.dart'; part 'src/amap_initializer.dart'; part 'src/amap_controller.dart'; part 'src/amap_widget.dart'; -part 'src/amap_loader.dart'; part 'src/utils/location_utils.dart'; diff --git a/lib/src/amap_controller.dart b/lib/src/amap_controller.dart index 2960c08..20ef0e8 100644 --- a/lib/src/amap_controller.dart +++ b/lib/src/amap_controller.dart @@ -55,43 +55,37 @@ class AMapController { _methodChannel .onCameraMove(mapId: mapId) .listen((CameraPositionMoveEvent e) { - _mapState._extensions.values.forEach((ext) => ext.onCameraMove(e.value)); _mapState.widget.onCameraMove?.call(e.value); + if (_mapState.widget.infoWindowAdapter != null) { + _mapState.updateMarkers(); + } }); _methodChannel .onCameraMoveEnd(mapId: mapId) .listen((CameraPositionMoveEndEvent e) { - _mapState._extensions.values - .forEach((ext) => ext.onCameraMoveEnd(e.value)); _mapState.widget.onCameraMoveEnd?.call(e.value); }); _methodChannel .onMapTap(mapId: mapId) .listen(((MapTapEvent e) => _mapState.widget.onTap?.call(e.value))); _methodChannel.onMapLongPress(mapId: mapId).listen(((MapLongPressEvent e) { - _mapState._extensions.values.forEach((ext) => ext.onLongPress(e.value)); _mapState.widget.onLongPress?.call(e.value); })); _methodChannel.onPoiTouched(mapId: mapId).listen(((MapPoiTouchEvent e) { - _mapState._extensions.values.forEach((ext) => ext.onPoiTouched(e.value)); _mapState.widget.onPoiTouched?.call(e.value); })); _methodChannel.onMarkerTap(mapId: mapId).listen((MarkerTapEvent e) { - _mapState._extensions.values.forEach((ext) => ext.onMarkerTap(e.value)); _mapState.onMarkerTap(e.value); }); _methodChannel.onMarkerDragEnd(mapId: mapId).listen((MarkerDragEndEvent e) { - _mapState._extensions.values - .forEach((ext) => ext.onMarkerDragEnd(e.value)); _mapState.onMarkerDragEnd(e.value, e.position); }); _methodChannel.onPolylineTap(mapId: mapId).listen((PolylineTapEvent e) { - _mapState._extensions.values.forEach((ext) => ext.onPolylineTap(e.value)); _mapState.onPolylineTap(e.value); }); } @@ -150,4 +144,12 @@ class AMapController { Future fromScreenCoordinate(ScreenCoordinate screenCoordinate) { return _methodChannel.fromScreenLocation(screenCoordinate, mapId: mapId); } + + Future getMapContentApprovalNumber() { + return _methodChannel.getMapContentApprovalNumber(mapId: mapId); + } + + Future getSatelliteImageApprovalNumber() { + return _methodChannel.getSatelliteImageApprovalNumber(mapId: mapId); + } } diff --git a/lib/src/amap_loader.dart b/lib/src/amap_loader.dart deleted file mode 100644 index 5aa1593..0000000 --- a/lib/src/amap_loader.dart +++ /dev/null @@ -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 extensions; - - @override - State 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 { - @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); - } -} diff --git a/lib/src/amap_widget.dart b/lib/src/amap_widget.dart index 0ec2ffe..13e247d 100644 --- a/lib/src/amap_widget.dart +++ b/lib/src/amap_widget.dart @@ -106,11 +106,11 @@ class AMapWidget extends StatefulWidget { ///需要应用到地图上的手势集合 final Set> gestureRecognizers; - final List extensions; - /// 设置地图语言 final MapLanguage? mapLanguage; + final InfoWindowAdapter? infoWindowAdapter; + /// 创建一个展示高德地图的widget /// /// 在app首次启动时必须传入高德合规声明配置[privacyStatement],后续如果没有变化不需要重复设置 @@ -152,8 +152,8 @@ class AMapWidget extends StatefulWidget { this.markers = const {}, this.polylines = const {}, this.polygons = const {}, - this.extensions = const [], this.mapLanguage, + this.infoWindowAdapter, this.logoPosition, this.logoBottomMargin, this.logoLeftMargin}) @@ -168,7 +168,7 @@ class _MapState extends State { Map _markers = {}; Map _polylines = {}; Map _polygons = {}; - Map _extensions = {}; + Map _infoWindows = {}; final Completer _controller = Completer(); late _AMapOptions _mapOptions; @@ -190,22 +190,19 @@ class _MapState extends State { onPlatformViewCreated, ); - return AMapLoader( - mapView: mapView, - extensions: widget.extensions, + return Stack( + children: [mapView, ..._infoWindows.values.nonNulls], ); } @override void initState() { - AMapLoader.prepare(); super.initState(); _mapOptions = _AMapOptions.fromWidget(widget); _markers = keyByMarkerId(widget.markers); _polygons = keyByPolygonId(widget.polygons); _polylines = keyByPolylineId(widget.polylines); - _extensions = keyByExtensionId(widget.extensions); print('initState AMapWidget'); } @@ -233,10 +230,9 @@ class _MapState extends State { void didUpdateWidget(covariant AMapWidget oldWidget) { super.didUpdateWidget(oldWidget); _updateOptions(); - _updateMarkers(); + updateMarkers(); _updatePolylines(); _updatePolygons(); - _updateExtensions(); } Future onPlatformViewCreated(int id) async { @@ -247,14 +243,6 @@ class _MapState extends State { ); _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; if (_onMapCreated != null) { _onMapCreated(controller); @@ -303,12 +291,24 @@ class _MapState extends State { _mapOptions = newOptions; } - void _updateMarkers() async { + void updateMarkers() async { final AMapController controller = await _controller.future; + MarkerUpdates markerUpdates = + MarkerUpdates.from(_markers.values.toSet(), widget.markers); + + markerUpdates.markerIdsToRemove?.forEach((markerId) { + _removeInfoWindow(markerId); + }); + // ignore: unawaited_futures - controller._updateMarkers( - MarkerUpdates.from(_markers.values.toSet(), widget.markers)); + controller._updateMarkers(markerUpdates); _markers = keyByMarkerId(widget.markers); + + if (widget.infoWindowAdapter != null) { + _markers.values.forEach((marker) { + _onInfoWindowUpdate(marker); + }); + } } void _updatePolylines() async { @@ -325,9 +325,19 @@ class _MapState extends State { _polygons = keyByPolygonId(widget.polygons); } - void _updateExtensions() async { - // final AMapController controller = await _controller.future; - _extensions = keyByExtensionId(widget.extensions); + void _onInfoWindowUpdate(Marker marker) { + if (widget.infoWindowAdapter != null) { + setState(() { + _infoWindows[marker.id] = + widget.infoWindowAdapter!.getInfoWindow(context, marker); + }); + } + } + + void _removeInfoWindow(String markerId) { + setState(() { + _infoWindows.remove(markerId); + }); } } diff --git a/lib/src/core/method_channel_amap_map.dart b/lib/src/core/method_channel_amap_map.dart index 40af5f6..7b6f84a 100644 --- a/lib/src/core/method_channel_amap_map.dart +++ b/lib/src/core/method_channel_amap_map.dart @@ -284,4 +284,20 @@ class MethodChannelAMapFlutterMap implements AMapFlutterPlatform { 'map#fromScreenCoordinate', screenCoordinate.toJson()); return LatLng(latLng![0] as double, latLng[1] as double); } + + Future getMapContentApprovalNumber({ + required int mapId, + }) async { + return await channel(mapId) + .invokeMethod('map#contentApprovalNumber') ?? + ''; + } + + Future getSatelliteImageApprovalNumber({ + required int mapId, + }) async { + return await channel(mapId) + .invokeMethod('map#satelliteImageApprovalNumber') ?? + ''; + } } diff --git a/lib/src/extension/buildin/info_window_extension.dart b/lib/src/extension/buildin/info_window_extension.dart deleted file mode 100644 index c33aec1..0000000 --- a/lib/src/extension/buildin/info_window_extension.dart +++ /dev/null @@ -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.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.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( - 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}'; - } -} diff --git a/lib/src/extension/extensions.dart b/lib/src/extension/extensions.dart deleted file mode 100644 index c41447d..0000000 --- a/lib/src/extension/extensions.dart +++ /dev/null @@ -1 +0,0 @@ -export 'buildin/info_window_extension.dart'; diff --git a/lib/src/types/amap_extension.dart b/lib/src/types/amap_extension.dart deleted file mode 100644 index b37248b..0000000 --- a/lib/src/types/amap_extension.dart +++ /dev/null @@ -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 keyByExtensionId( - Iterable extensions) { - // ignore: unnecessary_null_comparison - if (extensions == null) { - return {}; - } - return Map.fromEntries(extensions.map( - (AMapExtension extension) => - MapEntry(extension.id, extension))); -} diff --git a/lib/src/types/extension_context.dart b/lib/src/types/extension_context.dart deleted file mode 100644 index db1e356..0000000 --- a/lib/src/types/extension_context.dart +++ /dev/null @@ -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, -} diff --git a/lib/src/types/info_window_adapter.dart b/lib/src/types/info_window_adapter.dart new file mode 100644 index 0000000..9fcd951 --- /dev/null +++ b/lib/src/types/info_window_adapter.dart @@ -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); +} diff --git a/lib/src/types/types.dart b/lib/src/types/types.dart index 85d0594..1adb06a 100644 --- a/lib/src/types/types.dart +++ b/lib/src/types/types.dart @@ -20,8 +20,5 @@ export 'polyline_updates.dart'; export 'polygon.dart'; export 'polygon_updates.dart'; export 'bitmap.dart'; -export 'extension_context.dart'; -export 'amap_extension.dart'; export 'screen_coordinate.dart'; - -export '../extension/extensions.dart'; +export 'info_window_adapter.dart'; diff --git a/pubspec.yaml b/pubspec.yaml index d3f111b..1b4061b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: amap_map 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 issue_tracker: https://github.com/kuloud/amap_map/issues platforms: