expo-gaode-map 2.2.39-next.0 → 2.2.40-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -224,6 +224,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
224
224
  private val mainHandler = Handler(Looper.getMainLooper())
225
225
  private var isRemoving = false // 标记是否正在被移除
226
226
  private var pendingMarkerIconUpdate: Runnable? = null
227
+ private var pendingDetachRemovalTask: Runnable? = null
227
228
  private var lastAppliedCustomMarkerKey: String? = null
228
229
 
229
230
  // 缓存属性,在 marker 创建前保存
@@ -482,9 +483,10 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
482
483
 
483
484
  cacheKey = key
484
485
  if (isNotEmpty()) {
485
- // cacheKey 通常和 selected/zoom level 同帧变化。延后一帧截图,避免在 RN
486
- // children 样式尚未完成更新时生成空图,同时保留旧图直到新图准备好。
487
- scheduleMarkerIconUpdate(32)
486
+ // cacheKey 通常和 selected/zoom level 同帧变化。先淘汰当前 key 可能存在的旧截图,
487
+ // 再延后一帧重绘,避免切换选中态时命中 stale bitmap。
488
+ invalidateCurrentSnapshotCache()
489
+ markCustomMarkerContentDirty(32)
488
490
  } else {
489
491
  pendingIconUri?.let { iconUri ->
490
492
  marker?.let { loadAndSetIcon(iconUri, it) }
@@ -1000,6 +1002,11 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
1000
1002
  }
1001
1003
  }
1002
1004
 
1005
+ private fun cancelPendingMarkerIconUpdate() {
1006
+ pendingMarkerIconUpdate?.let { mainHandler.removeCallbacks(it) }
1007
+ pendingMarkerIconUpdate = null
1008
+ }
1009
+
1003
1010
  private fun invalidateAppliedCustomMarkerCaches(clearGlobalCache: Boolean) {
1004
1011
  val key = lastAppliedCustomMarkerKey ?: return
1005
1012
  if (clearGlobalCache) {
@@ -1009,6 +1016,12 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
1009
1016
  lastAppliedCustomMarkerKey = null
1010
1017
  }
1011
1018
 
1019
+ private fun invalidateCurrentSnapshotCache() {
1020
+ val key = resolveMarkerBitmapSnapshot()?.fullCacheKey ?: return
1021
+ BitmapDescriptorCache.remove(key)
1022
+ IconBitmapCache.remove(key)
1023
+ }
1024
+
1012
1025
  private fun markCustomMarkerContentDirty(delayMs: Long = 16L) {
1013
1026
  if (isRemoving || isEmpty()) {
1014
1027
  return
@@ -1331,6 +1344,9 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
1331
1344
  * 移除标记
1332
1345
  */
1333
1346
  fun removeMarker() {
1347
+ cancelPendingDetachRemoval()
1348
+ cancelPendingMarkerIconUpdate()
1349
+
1334
1350
  // 停止平滑移动
1335
1351
  stopSmoothMove()
1336
1352
  smoothMoveMarker?.destroy()
@@ -1343,20 +1359,30 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
1343
1359
  marker = null
1344
1360
  }
1345
1361
 
1362
+ override fun onAttachedToWindow() {
1363
+ super.onAttachedToWindow()
1364
+ cancelPendingDetachRemoval()
1365
+ isRemoving = false
1366
+
1367
+ if (isNotEmpty() && marker != null) {
1368
+ scheduleMarkerIconUpdate(16)
1369
+ }
1370
+ }
1371
+
1346
1372
  override fun onDetachedFromWindow() {
1347
1373
  super.onDetachedFromWindow()
1348
1374
 
1349
1375
  // 🔑 关键修复:使用 post 延迟检查
1350
- // 清理所有延迟任务
1351
- mainHandler.removeCallbacksAndMessages(null)
1352
- pendingMarkerIconUpdate = null
1376
+ cancelPendingDetachRemoval()
1353
1377
 
1354
1378
  // 延迟检查 parent 状态。React 更新 children 时可能会短暂 detach/attach,
1355
1379
  // 过早删除会导致点击后其它 Marker 消失。
1356
- mainHandler.postDelayed({
1380
+ val task = Runnable {
1381
+ pendingDetachRemovalTask = null
1357
1382
  if (parent == null) {
1358
1383
  // 标记正在移除
1359
1384
  isRemoving = true
1385
+ cancelPendingMarkerIconUpdate()
1360
1386
 
1361
1387
  // 🔑 修复:不要清空全局缓存
1362
1388
  // 理由:会影响其他 Marker 的性能
@@ -1365,7 +1391,14 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
1365
1391
  // 移除 marker
1366
1392
  removeMarker()
1367
1393
  }
1368
- }, 500)
1394
+ }
1395
+ pendingDetachRemovalTask = task
1396
+ mainHandler.postDelayed(task, 500)
1397
+ }
1398
+
1399
+ private fun cancelPendingDetachRemoval() {
1400
+ pendingDetachRemovalTask?.let { mainHandler.removeCallbacks(it) }
1401
+ pendingDetachRemovalTask = null
1369
1402
  }
1370
1403
 
1371
1404
  }
@@ -69,7 +69,7 @@ export interface MapViewProps {
69
69
  userLocationRepresentation?: {
70
70
  /** 精度圈是否显示 @default true */
71
71
  showsAccuracyRing?: boolean;
72
- /** 是否显示方向指示 @default true @platform ios */
72
+ /** 是否显示 SDK 方向指示扇形;iOS 无默认箭头图片,如需箭头请配合 image 传自定义定位图 @default true @platform ios */
73
73
  showsHeadingIndicator?: boolean;
74
74
  /** 精度圈填充颜色 支持 '#RRGGBB'、'red' 或 ARGB 数字 */
75
75
  fillColor?: string | number;
@@ -105,7 +105,7 @@ export interface MapViewProps {
105
105
  *
106
106
  * 🧭 **方向指示说明**:
107
107
  * - Android 通过 locationType 实现方向指示(定位点依照设备方向旋转)
108
- * - iOS 通过 showsHeadingIndicator 实现方向指示(显示扇形方向指示器)
108
+ * - iOS 通过 showsHeadingIndicator 显示方向指示扇形;SDK 无默认箭头图片,如需箭头请配合 image 传自定义定位图
109
109
  *
110
110
  * 📱 **Android 方向指示模式**(推荐使用以下两种):
111
111
  * - 'LOCATION_ROTATE': 定位点依照设备方向旋转,视角跟随移动到中心
@@ -1 +1 @@
1
- {"version":3,"file":"map-view.types.d.ts","sourceRoot":"","sources":["../../src/types/map-view.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"map-view.types.d.ts","sourceRoot":"","sources":["../../src/types/map-view.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"map-view.types.js","sourceRoot":"","sources":["../../src/types/map-view.types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * 高德地图视图相关类型定义\n * 基于 Expo Modules API\n */\n\nimport type { StyleProp, ViewStyle, NativeSyntheticEvent } from 'react-native';\nimport type { CameraPosition, CameraUpdate, LatLng, LatLngBounds, MapPoi, MapType, Point, LatLngPoint } from './common.types';\nimport type { Coordinates, ReGeocode, HeadingUpdate } from './location.types';\nimport type { FitToCoordinatesOptions } from './route-playback.types';\n\n/**\n * 定位事件数据\n */\nexport interface LocationEvent {\n /**\n * 纬度\n */\n latitude: number;\n \n /**\n * 经度\n */\n longitude: number;\n \n /**\n * 定位精度(米)\n */\n accuracy: number;\n}\n\n\n/**\n * 地图相机事件\n */\nexport interface CameraEvent {\n /**\n * 相机位置\n */\n cameraPosition: CameraPosition;\n\n /**\n * 可见区域边界\n */\n latLngBounds: LatLngBounds;\n}\n\n/**\n * 缩放手势锚点\n * - `gesture`: 跟随手势中心点缩放(默认)\n * - `center`: 固定地图中心点缩放\n */\nexport type ZoomGestureAnchor = 'gesture' | 'center';\n\n/**\n * 地图视图属性\n */\nexport interface MapViewProps {\n /**\n * 地图类型\n */\n mapType?: MapType;\n\n /**\n * 初始相机位置\n */\n initialCameraPosition?: CameraPosition;\n\n /**\n * 是否显示当前定位\n */\n myLocationEnabled?: boolean;\n\n /**\n * 是否跟随用户位置\n * @default false\n */\n followUserLocation?: boolean;\n\n /**\n * 定位蓝点配置\n */\n userLocationRepresentation?: {\n /** 精度圈是否显示 @default true */\n showsAccuracyRing?: boolean;\n /** 是否显示方向指示 @default true @platform ios */\n showsHeadingIndicator?: boolean;\n /** 精度圈填充颜色 支持 '#RRGGBB'、'red' 或 ARGB 数字 */\n fillColor?: string | number;\n /** 精度圈边线颜色 */\n strokeColor?: string | number;\n /** 精度圈边线宽度 @default 0 */\n lineWidth?: number;\n /** 内部蓝色圆点是否使用律动效果 @default true @platform ios */\n enablePulseAnimation?: boolean;\n /** 定位点背景色 @default 'white' @platform ios */\n locationDotBgColor?: string | number;\n /** 定位点蓝色圆点颜色 @default 'blue' @platform ios */\n locationDotFillColor?: string | number;\n /** 定位图标 支持网络图片(http/https)、本地文件(file://)或资源名称 */\n image?: string;\n /** 定位图标宽度(像素) */\n imageWidth?: number;\n /** 定位图标高度(像素) */\n imageHeight?: number;\n /**\n * 是否显示定位蓝点 @default true\n * - iOS: 对应 mapView.showsUserLocation\n * - Android: 对应 MyLocationStyle.showMyLocation() (5.1.0+)\n */\n showMyLocation?: boolean;\n /** 定位图标锚点 U 坐标 (0.0-1.0) @platform android */\n anchorU?: number;\n /** 定位图标锚点 V 坐标 (0.0-1.0) @platform android */\n anchorV?: number;\n /**\n * 定位蓝点展现模式 @platform android\n * @default 'LOCATION_ROTATE_NO_CENTER' (连续定位、定位点旋转、不移动到中心)\n *\n * 🧭 **方向指示说明**:\n * - Android 通过 locationType 实现方向指示(定位点依照设备方向旋转)\n * - iOS 通过 showsHeadingIndicator 实现方向指示(显示扇形方向指示器)\n *\n * 📱 **Android 方向指示模式**(推荐使用以下两种):\n * - 'LOCATION_ROTATE': 定位点依照设备方向旋转,视角跟随移动到中心\n * - 'LOCATION_ROTATE_NO_CENTER': 定位点依照设备方向旋转,视角不移动到中心 ⭐\n *\n * 🗺️ **其他模式**:\n * - 'SHOW': 只定位一次\n * - 'LOCATE': 定位一次,且将视角移动到地图中心点\n * - 'FOLLOW': 连续定位、跟随移动,但定位点不旋转\n * - 'MAP_ROTATE': 地图依照设备方向旋转(而非定位点旋转)\n * - 'FOLLOW_NO_CENTER': 连续定位、不移动到中心,定位点不旋转\n * - 'MAP_ROTATE_NO_CENTER': 地图依照设备方向旋转,不移动到中心\n *\n * 显式设置 locationType 时,会覆盖 followUserLocation 的默认模式选择。\n */\n locationType?: 'SHOW' | 'LOCATE' | 'FOLLOW' | 'MAP_ROTATE' | 'LOCATION_ROTATE' |\n 'LOCATION_ROTATE_NO_CENTER' | 'FOLLOW_NO_CENTER' | 'MAP_ROTATE_NO_CENTER';\n };\n\n /**\n * 是否显示室内地图\n * \n */\n indoorViewEnabled?: boolean;\n\n /**\n * 是否显示3D建筑\n */\n buildingsEnabled?: boolean;\n\n /**\n * 是否显示标注\n * @platform android\n * @note iOS 暂不支持\n */\n labelsEnabled?: boolean;\n\n /**\n * 是否显示指南针\n */\n compassEnabled?: boolean;\n\n /**\n * 是否显示缩放按钮\n * @platform android\n */\n zoomControlsEnabled?: boolean;\n\n /**\n * 是否显示比例尺\n */\n scaleControlsEnabled?: boolean;\n\n /**\n * 是否显示定位按钮\n * @platform android\n */\n myLocationButtonEnabled?: boolean;\n\n /**\n * 是否显示路况\n */\n trafficEnabled?: boolean;\n\n /**\n * 最大缩放级别\n */\n maxZoom?: number;\n\n /**\n * 最小缩放级别\n */\n minZoom?: number;\n\n /**\n * 是否启用缩放手势\n */\n zoomGesturesEnabled?: boolean;\n\n /**\n * 缩放手势锚点\n * @default 'gesture'\n */\n zoomGestureAnchor?: ZoomGestureAnchor;\n\n /**\n * 是否启用滑动手势\n */\n scrollGesturesEnabled?: boolean;\n\n /**\n * 是否启用旋转手势\n */\n rotateGesturesEnabled?: boolean;\n\n /**\n * 是否启用倾斜手势\n */\n tiltGesturesEnabled?: boolean;\n\n /**\n * 定位的最小更新距离(米)\n * @platform ios\n */\n distanceFilter?: number;\n\n /**\n * 最小更新角度(度)\n * @platform ios\n */\n headingFilter?: number;\n\n /**\n * 是否启用国内外地图自动切换\n * - true: 当中心点在国外时自动切换到苹果地图(iOS),国内时切换回高德地图\n * - false: 始终使用高德地图\n * @platform ios 当前仅支持 iOS 安卓因为需要使用 Google Maps SDK和谷歌服务\n * @default false\n */\n worldMapSwitchEnabled?: boolean;\n\n /**\n * 自定义地图样式\n *\n * 支持两种方式:\n * 1. 在线样式:提供 styleId(从高德开放平台获取)\n * 2. 本地样式:提供 styleDataPath 和可选的 extraStyleDataPath\n *\n * @example\n * // 使用在线样式\n * customMapStyle={{ styleId: \"your-style-id\" }}\n *\n * @example\n * // 使用本地样式文件\n * customMapStyle={{\n * styleDataPath: \"path/to/style.data\",\n * extraStyleDataPath: \"path/to/extra.data\"\n * }}\n */\n customMapStyle?: {\n /** 在线样式ID(从高德开放平台获取) */\n styleId?: string;\n /** 本地样式文件路径 */\n styleDataPath?: string;\n /** 额外样式文件路径(可选) */\n extraStyleDataPath?: string;\n };\n\n /**\n * 样式\n */\n style?: StyleProp<ViewStyle>;\n\n /**\n * 点击地图事件\n */\n onMapPress?: (event: NativeSyntheticEvent<LatLng>) => void;\n\n /**\n * 点击标注点事件\n */\n onPressPoi?: (event: NativeSyntheticEvent<MapPoi>) => void;\n\n /**\n * 长按地图事件\n */\n onMapLongPress?: (event: NativeSyntheticEvent<LatLng>) => void;\n\n /**\n * 地图状态改变事件(实时触发)\n * 可配合 `cameraEventThrottleMs` 控制事件频率\n */\n onCameraMove?: (event: NativeSyntheticEvent<CameraEvent>) => void;\n\n /**\n * 地图移动事件节流间隔(毫秒)\n * `0` 表示不节流\n * @default 32\n */\n cameraEventThrottleMs?: number;\n\n /**\n * 地图状态改变完成事件\n */\n onCameraIdle?: (event: NativeSyntheticEvent<CameraEvent>) => void;\n\n /**\n * 地图加载完成事件\n */\n onLoad?: (event: NativeSyntheticEvent<{}>) => void;\n\n /**\n * 地图定位更新事件\n */\n onLocation?: (event: NativeSyntheticEvent<LocationEvent>) => void;\n\n /**\n * 子组件\n */\n children?: React.ReactNode;\n}\n\n\n/**\n * 地图视图方法\n */\nexport interface MapViewMethods {\n /**\n * 移动相机\n * @param cameraPosition 目标相机位置\n * @param duration 动画时长(毫秒)\n */\n moveCamera(cameraPosition: CameraUpdate, duration?: number): Promise<void>;\n\n /**\n * 将屏幕坐标转换为地理坐标\n * @param point 屏幕坐标\n * @returns 地理坐标\n */\n getLatLng(point: Point): Promise<LatLng>;\n\n /**\n * 设置地图中心点\n * @param center 中心点\n * @param animated 是否启用动画\n */\n setCenter(center: LatLngPoint, animated?: boolean): Promise<void>;\n\n /**\n * 设置地图缩放级别\n * @param zoom 缩放级别\n * @param animated 是否启用动画\n */\n setZoom(zoom: number, animated?: boolean): Promise<void>;\n\n /**\n * 获取相机位置\n * @returns 相机位置\n */\n getCameraPosition(): Promise<CameraPosition>;\n\n /**\n * 截取地图快照\n * @returns 快照图片文件路径\n */\n takeSnapshot(): Promise<string>;\n\n /**\n * 根据坐标集合自动移动相机\n */\n fitToCoordinates(points: LatLngPoint[], options?: FitToCoordinatesOptions): Promise<void>;\n}\n\n/**\n * MapView Ref 公开接口(用户使用)\n */\nexport interface MapViewRef {\n moveCamera(position: CameraUpdate, duration?: number): Promise<void>;\n getLatLng(point: Point): Promise<LatLng>;\n setCenter(center: LatLngPoint, animated?: boolean): Promise<void>;\n setZoom(zoom: number, animated?: boolean): Promise<void>;\n getCameraPosition(): Promise<CameraPosition>;\n takeSnapshot(): Promise<string>;\n fitToCoordinates(points: LatLngPoint[], options?: FitToCoordinatesOptions): Promise<void>;\n}\n\n/**\n * Expo 模块事件类型\n * 定义了原生模块可以触发的事件\n */\nexport type ExpoGaodeMapModuleEvents = {\n /**\n * 定位更新事件\n * 当位置发生变化时触发\n * @param location 位置信息,包含坐标和可选的逆地理编码信息\n */\n onLocationUpdate: (location: Coordinates | ReGeocode) => void;\n \n /**\n * 方向更新事件(iOS)\n * 当设备方向发生变化时触发\n * @param heading 方向信息\n */\n onHeadingUpdate: (heading: HeadingUpdate) => void;\n};\n"]}
1
+ {"version":3,"file":"map-view.types.js","sourceRoot":"","sources":["../../src/types/map-view.types.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * 高德地图视图相关类型定义\n * 基于 Expo Modules API\n */\n\nimport type { StyleProp, ViewStyle, NativeSyntheticEvent } from 'react-native';\nimport type { CameraPosition, CameraUpdate, LatLng, LatLngBounds, MapPoi, MapType, Point, LatLngPoint } from './common.types';\nimport type { Coordinates, ReGeocode, HeadingUpdate } from './location.types';\nimport type { FitToCoordinatesOptions } from './route-playback.types';\n\n/**\n * 定位事件数据\n */\nexport interface LocationEvent {\n /**\n * 纬度\n */\n latitude: number;\n \n /**\n * 经度\n */\n longitude: number;\n \n /**\n * 定位精度(米)\n */\n accuracy: number;\n}\n\n\n/**\n * 地图相机事件\n */\nexport interface CameraEvent {\n /**\n * 相机位置\n */\n cameraPosition: CameraPosition;\n\n /**\n * 可见区域边界\n */\n latLngBounds: LatLngBounds;\n}\n\n/**\n * 缩放手势锚点\n * - `gesture`: 跟随手势中心点缩放(默认)\n * - `center`: 固定地图中心点缩放\n */\nexport type ZoomGestureAnchor = 'gesture' | 'center';\n\n/**\n * 地图视图属性\n */\nexport interface MapViewProps {\n /**\n * 地图类型\n */\n mapType?: MapType;\n\n /**\n * 初始相机位置\n */\n initialCameraPosition?: CameraPosition;\n\n /**\n * 是否显示当前定位\n */\n myLocationEnabled?: boolean;\n\n /**\n * 是否跟随用户位置\n * @default false\n */\n followUserLocation?: boolean;\n\n /**\n * 定位蓝点配置\n */\n userLocationRepresentation?: {\n /** 精度圈是否显示 @default true */\n showsAccuracyRing?: boolean;\n /** 是否显示 SDK 方向指示扇形;iOS 无默认箭头图片,如需箭头请配合 image 传自定义定位图 @default true @platform ios */\n showsHeadingIndicator?: boolean;\n /** 精度圈填充颜色 支持 '#RRGGBB'、'red' 或 ARGB 数字 */\n fillColor?: string | number;\n /** 精度圈边线颜色 */\n strokeColor?: string | number;\n /** 精度圈边线宽度 @default 0 */\n lineWidth?: number;\n /** 内部蓝色圆点是否使用律动效果 @default true @platform ios */\n enablePulseAnimation?: boolean;\n /** 定位点背景色 @default 'white' @platform ios */\n locationDotBgColor?: string | number;\n /** 定位点蓝色圆点颜色 @default 'blue' @platform ios */\n locationDotFillColor?: string | number;\n /** 定位图标 支持网络图片(http/https)、本地文件(file://)或资源名称 */\n image?: string;\n /** 定位图标宽度(像素) */\n imageWidth?: number;\n /** 定位图标高度(像素) */\n imageHeight?: number;\n /**\n * 是否显示定位蓝点 @default true\n * - iOS: 对应 mapView.showsUserLocation\n * - Android: 对应 MyLocationStyle.showMyLocation() (5.1.0+)\n */\n showMyLocation?: boolean;\n /** 定位图标锚点 U 坐标 (0.0-1.0) @platform android */\n anchorU?: number;\n /** 定位图标锚点 V 坐标 (0.0-1.0) @platform android */\n anchorV?: number;\n /**\n * 定位蓝点展现模式 @platform android\n * @default 'LOCATION_ROTATE_NO_CENTER' (连续定位、定位点旋转、不移动到中心)\n *\n * 🧭 **方向指示说明**:\n * - Android 通过 locationType 实现方向指示(定位点依照设备方向旋转)\n * - iOS 通过 showsHeadingIndicator 显示方向指示扇形;SDK 无默认箭头图片,如需箭头请配合 image 传自定义定位图\n *\n * 📱 **Android 方向指示模式**(推荐使用以下两种):\n * - 'LOCATION_ROTATE': 定位点依照设备方向旋转,视角跟随移动到中心\n * - 'LOCATION_ROTATE_NO_CENTER': 定位点依照设备方向旋转,视角不移动到中心 ⭐\n *\n * 🗺️ **其他模式**:\n * - 'SHOW': 只定位一次\n * - 'LOCATE': 定位一次,且将视角移动到地图中心点\n * - 'FOLLOW': 连续定位、跟随移动,但定位点不旋转\n * - 'MAP_ROTATE': 地图依照设备方向旋转(而非定位点旋转)\n * - 'FOLLOW_NO_CENTER': 连续定位、不移动到中心,定位点不旋转\n * - 'MAP_ROTATE_NO_CENTER': 地图依照设备方向旋转,不移动到中心\n *\n * 显式设置 locationType 时,会覆盖 followUserLocation 的默认模式选择。\n */\n locationType?: 'SHOW' | 'LOCATE' | 'FOLLOW' | 'MAP_ROTATE' | 'LOCATION_ROTATE' |\n 'LOCATION_ROTATE_NO_CENTER' | 'FOLLOW_NO_CENTER' | 'MAP_ROTATE_NO_CENTER';\n };\n\n /**\n * 是否显示室内地图\n * \n */\n indoorViewEnabled?: boolean;\n\n /**\n * 是否显示3D建筑\n */\n buildingsEnabled?: boolean;\n\n /**\n * 是否显示标注\n * @platform android\n * @note iOS 暂不支持\n */\n labelsEnabled?: boolean;\n\n /**\n * 是否显示指南针\n */\n compassEnabled?: boolean;\n\n /**\n * 是否显示缩放按钮\n * @platform android\n */\n zoomControlsEnabled?: boolean;\n\n /**\n * 是否显示比例尺\n */\n scaleControlsEnabled?: boolean;\n\n /**\n * 是否显示定位按钮\n * @platform android\n */\n myLocationButtonEnabled?: boolean;\n\n /**\n * 是否显示路况\n */\n trafficEnabled?: boolean;\n\n /**\n * 最大缩放级别\n */\n maxZoom?: number;\n\n /**\n * 最小缩放级别\n */\n minZoom?: number;\n\n /**\n * 是否启用缩放手势\n */\n zoomGesturesEnabled?: boolean;\n\n /**\n * 缩放手势锚点\n * @default 'gesture'\n */\n zoomGestureAnchor?: ZoomGestureAnchor;\n\n /**\n * 是否启用滑动手势\n */\n scrollGesturesEnabled?: boolean;\n\n /**\n * 是否启用旋转手势\n */\n rotateGesturesEnabled?: boolean;\n\n /**\n * 是否启用倾斜手势\n */\n tiltGesturesEnabled?: boolean;\n\n /**\n * 定位的最小更新距离(米)\n * @platform ios\n */\n distanceFilter?: number;\n\n /**\n * 最小更新角度(度)\n * @platform ios\n */\n headingFilter?: number;\n\n /**\n * 是否启用国内外地图自动切换\n * - true: 当中心点在国外时自动切换到苹果地图(iOS),国内时切换回高德地图\n * - false: 始终使用高德地图\n * @platform ios 当前仅支持 iOS 安卓因为需要使用 Google Maps SDK和谷歌服务\n * @default false\n */\n worldMapSwitchEnabled?: boolean;\n\n /**\n * 自定义地图样式\n *\n * 支持两种方式:\n * 1. 在线样式:提供 styleId(从高德开放平台获取)\n * 2. 本地样式:提供 styleDataPath 和可选的 extraStyleDataPath\n *\n * @example\n * // 使用在线样式\n * customMapStyle={{ styleId: \"your-style-id\" }}\n *\n * @example\n * // 使用本地样式文件\n * customMapStyle={{\n * styleDataPath: \"path/to/style.data\",\n * extraStyleDataPath: \"path/to/extra.data\"\n * }}\n */\n customMapStyle?: {\n /** 在线样式ID(从高德开放平台获取) */\n styleId?: string;\n /** 本地样式文件路径 */\n styleDataPath?: string;\n /** 额外样式文件路径(可选) */\n extraStyleDataPath?: string;\n };\n\n /**\n * 样式\n */\n style?: StyleProp<ViewStyle>;\n\n /**\n * 点击地图事件\n */\n onMapPress?: (event: NativeSyntheticEvent<LatLng>) => void;\n\n /**\n * 点击标注点事件\n */\n onPressPoi?: (event: NativeSyntheticEvent<MapPoi>) => void;\n\n /**\n * 长按地图事件\n */\n onMapLongPress?: (event: NativeSyntheticEvent<LatLng>) => void;\n\n /**\n * 地图状态改变事件(实时触发)\n * 可配合 `cameraEventThrottleMs` 控制事件频率\n */\n onCameraMove?: (event: NativeSyntheticEvent<CameraEvent>) => void;\n\n /**\n * 地图移动事件节流间隔(毫秒)\n * `0` 表示不节流\n * @default 32\n */\n cameraEventThrottleMs?: number;\n\n /**\n * 地图状态改变完成事件\n */\n onCameraIdle?: (event: NativeSyntheticEvent<CameraEvent>) => void;\n\n /**\n * 地图加载完成事件\n */\n onLoad?: (event: NativeSyntheticEvent<{}>) => void;\n\n /**\n * 地图定位更新事件\n */\n onLocation?: (event: NativeSyntheticEvent<LocationEvent>) => void;\n\n /**\n * 子组件\n */\n children?: React.ReactNode;\n}\n\n\n/**\n * 地图视图方法\n */\nexport interface MapViewMethods {\n /**\n * 移动相机\n * @param cameraPosition 目标相机位置\n * @param duration 动画时长(毫秒)\n */\n moveCamera(cameraPosition: CameraUpdate, duration?: number): Promise<void>;\n\n /**\n * 将屏幕坐标转换为地理坐标\n * @param point 屏幕坐标\n * @returns 地理坐标\n */\n getLatLng(point: Point): Promise<LatLng>;\n\n /**\n * 设置地图中心点\n * @param center 中心点\n * @param animated 是否启用动画\n */\n setCenter(center: LatLngPoint, animated?: boolean): Promise<void>;\n\n /**\n * 设置地图缩放级别\n * @param zoom 缩放级别\n * @param animated 是否启用动画\n */\n setZoom(zoom: number, animated?: boolean): Promise<void>;\n\n /**\n * 获取相机位置\n * @returns 相机位置\n */\n getCameraPosition(): Promise<CameraPosition>;\n\n /**\n * 截取地图快照\n * @returns 快照图片文件路径\n */\n takeSnapshot(): Promise<string>;\n\n /**\n * 根据坐标集合自动移动相机\n */\n fitToCoordinates(points: LatLngPoint[], options?: FitToCoordinatesOptions): Promise<void>;\n}\n\n/**\n * MapView Ref 公开接口(用户使用)\n */\nexport interface MapViewRef {\n moveCamera(position: CameraUpdate, duration?: number): Promise<void>;\n getLatLng(point: Point): Promise<LatLng>;\n setCenter(center: LatLngPoint, animated?: boolean): Promise<void>;\n setZoom(zoom: number, animated?: boolean): Promise<void>;\n getCameraPosition(): Promise<CameraPosition>;\n takeSnapshot(): Promise<string>;\n fitToCoordinates(points: LatLngPoint[], options?: FitToCoordinatesOptions): Promise<void>;\n}\n\n/**\n * Expo 模块事件类型\n * 定义了原生模块可以触发的事件\n */\nexport type ExpoGaodeMapModuleEvents = {\n /**\n * 定位更新事件\n * 当位置发生变化时触发\n * @param location 位置信息,包含坐标和可选的逆地理编码信息\n */\n onLocationUpdate: (location: Coordinates | ReGeocode) => void;\n \n /**\n * 方向更新事件(iOS)\n * 当设备方向发生变化时触发\n * @param heading 方向信息\n */\n onHeadingUpdate: (heading: HeadingUpdate) => void;\n};\n"]}
@@ -102,6 +102,8 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
102
102
  private var uiManager: UIManager!
103
103
  /// 地图是否已加载完成
104
104
  private var isMapLoaded = false
105
+ /// 定位 annotation 首次出现后是否已补应用定位样式
106
+ private var hasAppliedUserLocationStyleAfterLocationUpdate = false
105
107
  /// 初始相机是否已应用(仅应用一次,避免与运行时相机控制冲突)
106
108
  private var hasAppliedInitialCameraPosition = false
107
109
  /// 是否正在处理 annotation 选择事件
@@ -378,6 +380,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
378
380
  uiManager.setRotateEnabled(isRotateEnabled)
379
381
  uiManager.setTiltEnabled(isTiltEnabled)
380
382
  uiManager.setShowsUserLocation(showsUserLocation, followUser: followUserLocation)
383
+ applyUserLocationStyle()
381
384
  }
382
385
 
383
386
  /**
@@ -406,6 +409,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
406
409
  uiManager.setRotateEnabled(isRotateEnabled)
407
410
  uiManager.setTiltEnabled(isTiltEnabled)
408
411
  uiManager.setShowsUserLocation(showsUserLocation, followUser: followUserLocation)
412
+ applyUserLocationStyle()
409
413
  uiManager.setShowsTraffic(showsTraffic)
410
414
  uiManager.setShowsBuildings(showsBuildings)
411
415
  uiManager.setShowsIndoorMap(showsIndoorMap)
@@ -633,6 +637,9 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
633
637
  func setFollowUserLocation(_ follow: Bool) {
634
638
  followUserLocation = follow
635
639
  uiManager?.setShowsUserLocation(showsUserLocation, followUser: follow)
640
+ if showsUserLocation {
641
+ applyUserLocationStyle()
642
+ }
636
643
  }
637
644
 
638
645
  func setShowsUserLocation(_ show: Bool) {
@@ -645,6 +652,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
645
652
 
646
653
  func setUserLocationRepresentation(_ config: [String: Any]) {
647
654
  userLocationRepresentation = config
655
+ hasAppliedUserLocationStyleAfterLocationUpdate = false
648
656
  if showsUserLocation {
649
657
  uiManager?.setUserLocationRepresentation(config)
650
658
  }
@@ -654,7 +662,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
654
662
  * 应用用户位置样式
655
663
  */
656
664
  private func applyUserLocationStyle() {
657
- guard let config = userLocationRepresentation else { return }
665
+ guard showsUserLocation, let config = userLocationRepresentation else { return }
658
666
  uiManager?.setUserLocationRepresentation(config)
659
667
  }
660
668
 
@@ -929,6 +937,7 @@ class ExpoGaodeMapView: ExpoView, MAMapViewDelegate, UIGestureRecognizerDelegate
929
937
  super.addSubview(resolvedMapView)
930
938
  isMapLoaded = false
931
939
  hasAppliedInitialCameraPosition = false
940
+ hasAppliedUserLocationStyleAfterLocationUpdate = false
932
941
 
933
942
  cameraManager = CameraManager(mapView: resolvedMapView)
934
943
  uiManager = UIManager(mapView: resolvedMapView)
@@ -1012,9 +1021,37 @@ extension ExpoGaodeMapView {
1012
1021
  if let styleData = customMapStyleData {
1013
1022
  uiManager?.setCustomMapStyle(styleData)
1014
1023
  }
1024
+
1025
+ applyUserLocationStyle()
1015
1026
 
1016
1027
  onLoad(["loaded": true])
1017
1028
  }
1029
+
1030
+ /**
1031
+ * 定位更新回调
1032
+ */
1033
+ public func mapView(_ mapView: MAMapView, didUpdate userLocation: MAUserLocation, updatingLocation: Bool) {
1034
+ guard updatingLocation, let location = userLocation.location else { return }
1035
+
1036
+ if !hasAppliedUserLocationStyleAfterLocationUpdate {
1037
+ applyUserLocationStyle()
1038
+ hasAppliedUserLocationStyleAfterLocationUpdate = true
1039
+ }
1040
+
1041
+ let latitude = location.coordinate.latitude
1042
+ let longitude = location.coordinate.longitude
1043
+ guard latitude >= -90 && latitude <= 90,
1044
+ longitude >= -180 && longitude <= 180 else {
1045
+ return
1046
+ }
1047
+
1048
+ onLocation([
1049
+ "latitude": latitude,
1050
+ "longitude": longitude,
1051
+ "accuracy": location.horizontalAccuracy,
1052
+ "timestamp": Date().timeIntervalSince1970 * 1000
1053
+ ])
1054
+ }
1018
1055
 
1019
1056
  /**
1020
1057
  * 地图区域即将改变时触发
@@ -1358,13 +1395,118 @@ extension ExpoGaodeMapView {
1358
1395
  handleGaodePoiTouch(pois)
1359
1396
  }
1360
1397
 
1398
+ private func getUserLocationAnnotationView(for mapView: MAMapView, annotation: MAAnnotation) -> MAAnnotationView? {
1399
+ guard let config = userLocationRepresentation,
1400
+ let imagePath = config["image"] as? String,
1401
+ !imagePath.isEmpty else {
1402
+ return nil
1403
+ }
1404
+
1405
+ let reuseId = "ExpoGaodeMapUserLocationStyleReuseIdentifier"
1406
+ let annotationView: MAAnnotationView
1407
+ if let reusableView = mapView.dequeueReusableAnnotationView(withIdentifier: reuseId) {
1408
+ annotationView = reusableView
1409
+ } else {
1410
+ annotationView = MAAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
1411
+ }
1412
+ annotationView.annotation = annotation
1413
+ annotationView.canShowCallout = false
1414
+
1415
+ let imageWidth = config["imageWidth"] as? Double
1416
+ let imageHeight = config["imageHeight"] as? Double
1417
+ let cacheKey = userLocationImageCacheKey(imagePath: imagePath, imageWidth: imageWidth, imageHeight: imageHeight)
1418
+ annotationView.accessibilityIdentifier = cacheKey
1419
+
1420
+ if let cached = IconBitmapCache.shared.image(forKey: cacheKey) {
1421
+ annotationView.image = cached
1422
+ return annotationView
1423
+ }
1424
+
1425
+ annotationView.image = nil
1426
+ loadUserLocationImage(imagePath: imagePath, imageWidth: imageWidth, imageHeight: imageHeight, cacheKey: cacheKey) { [weak annotationView] image in
1427
+ guard let annotationView = annotationView,
1428
+ annotationView.accessibilityIdentifier == cacheKey else {
1429
+ return
1430
+ }
1431
+ annotationView.image = image
1432
+ }
1433
+
1434
+ return annotationView
1435
+ }
1436
+
1437
+ private func userLocationImageCacheKey(imagePath: String, imageWidth: Double?, imageHeight: Double?) -> String {
1438
+ let widthPart = imageWidth.map { String(Int($0.rounded())) } ?? "auto"
1439
+ let heightPart = imageHeight.map { String(Int($0.rounded())) } ?? "auto"
1440
+ return "userLocation|\(imagePath)|\(widthPart)x\(heightPart)"
1441
+ }
1442
+
1443
+ private func loadUserLocationImage(
1444
+ imagePath: String,
1445
+ imageWidth: Double?,
1446
+ imageHeight: Double?,
1447
+ cacheKey: String,
1448
+ completion: @escaping (UIImage?) -> Void
1449
+ ) {
1450
+ let finish: (UIImage?) -> Void = { image in
1451
+ if let image = image {
1452
+ IconBitmapCache.shared.setImage(image, forKey: cacheKey)
1453
+ }
1454
+ DispatchQueue.main.async {
1455
+ completion(image)
1456
+ }
1457
+ }
1458
+
1459
+ if imagePath.hasPrefix("http://") || imagePath.hasPrefix("https://") {
1460
+ DispatchQueue.global(qos: .userInitiated).async { [weak self] in
1461
+ guard let self = self,
1462
+ let url = URL(string: imagePath),
1463
+ let data = try? Data(contentsOf: url),
1464
+ let image = UIImage(data: data) else {
1465
+ finish(nil)
1466
+ return
1467
+ }
1468
+ finish(self.resizeUserLocationImage(image, imageWidth: imageWidth, imageHeight: imageHeight))
1469
+ }
1470
+ return
1471
+ }
1472
+
1473
+ let image: UIImage?
1474
+ if imagePath.hasPrefix("file://") {
1475
+ let path = String(imagePath.dropFirst(7))
1476
+ image = UIImage(contentsOfFile: path)
1477
+ } else {
1478
+ image = UIImage(named: imagePath)
1479
+ }
1480
+
1481
+ guard let image = image else {
1482
+ finish(nil)
1483
+ return
1484
+ }
1485
+ finish(resizeUserLocationImage(image, imageWidth: imageWidth, imageHeight: imageHeight))
1486
+ }
1487
+
1488
+ private func resizeUserLocationImage(_ image: UIImage, imageWidth: Double?, imageHeight: Double?) -> UIImage {
1489
+ guard let imageWidth = imageWidth,
1490
+ let imageHeight = imageHeight,
1491
+ imageWidth > 0,
1492
+ imageHeight > 0 else {
1493
+ return image
1494
+ }
1495
+
1496
+ let targetSize = CGSize(width: imageWidth, height: imageHeight)
1497
+ let renderer = UIGraphicsImageRenderer(size: targetSize)
1498
+ return renderer.image { _ in
1499
+ image.draw(in: CGRect(origin: .zero, size: targetSize))
1500
+ }
1501
+ }
1502
+
1361
1503
  /**
1362
1504
  * 创建标注视图
1363
- * 定位蓝点返回 nil 使用系统默认样式
1505
+ * 定位蓝点默认返回 nil 使用系统样式;传入 image 时按官方建议自定义定位 annotationView。
1364
1506
  */
1365
1507
  public func mapView(_ mapView: MAMapView, viewFor annotation: MAAnnotation) -> MAAnnotationView? {
1366
1508
  if annotation.isKind(of: MAUserLocation.self) {
1367
- return nil
1509
+ return getUserLocationAnnotationView(for: mapView, annotation: annotation)
1368
1510
  }
1369
1511
 
1370
1512
  // 🔑 支持 MAAnimatedAnnotation(平滑移动)
@@ -172,6 +172,9 @@ class UIManager: NSObject, MAMapViewDelegate {
172
172
  // 是否显示方向指示
173
173
  if let showsHeadingIndicator = config["showsHeadingIndicator"] as? Bool {
174
174
  representation.showsHeadingIndicator = showsHeadingIndicator
175
+ if showsHeadingIndicator {
176
+ mapView.userTrackingMode = .followWithHeading
177
+ }
175
178
  }
176
179
 
177
180
  // 精度圈填充颜色
@@ -75,6 +75,12 @@ class MarkerView: ExpoView {
75
75
  private var pendingUpdateTask: DispatchWorkItem?
76
76
  /// 子视图变化后的延迟刷新任务
77
77
  private var pendingSubviewRefreshTask: DispatchWorkItem?
78
+ /// cacheKey 变化后的延迟刷新任务
79
+ private var pendingCacheKeyRefreshTask: DispatchWorkItem?
80
+ /// 视图 detach 后延迟确认移除 annotation,避免 React 更新时短暂 detach 导致闪烁
81
+ private var pendingAnnotationRemovalTask: DispatchWorkItem?
82
+ /// cacheKey 刷新代次,用于丢弃过期截图任务
83
+ private var cacheKeyRefreshGeneration: Int = 0
78
84
  /// 最近一次应用到 annotationView 的 children 结构签名
79
85
  private var lastRenderedChildrenSignature: String?
80
86
  /// 最近一次成功渲染的 children 图片,用于缓存未命中时避免闪烁
@@ -159,7 +165,7 @@ class MarkerView: ExpoView {
159
165
  guard cacheKey != key else { return }
160
166
  self.cacheKey = key
161
167
  if !subviews.isEmpty {
162
- scheduleChildrenImageRefresh()
168
+ scheduleCacheKeyChildrenImageRefresh()
163
169
  } else {
164
170
  refreshAnnotationAppearance()
165
171
  }
@@ -508,11 +514,11 @@ class MarkerView: ExpoView {
508
514
  /**
509
515
  * 将子视图转换为图片
510
516
  */
511
- private func createImageFromSubviews(size explicitSize: CGSize? = nil) -> UIImage? {
517
+ private func createImageFromSubviews(size explicitSize: CGSize? = nil, cacheImage: Bool = true) -> UIImage? {
512
518
  let size = explicitSize ?? resolvedContentSubviewSize(defaultSize: CGSize(width: 200, height: 60))
513
519
  let key = childrenCacheKey(for: size)
514
520
 
515
- if let cachedImage = IconBitmapCache.shared.image(forKey: key) {
521
+ if cacheImage, let cachedImage = IconBitmapCache.shared.image(forKey: key) {
516
522
  return cachedImage
517
523
  }
518
524
 
@@ -553,7 +559,9 @@ class MarkerView: ExpoView {
553
559
 
554
560
 
555
561
 
556
- IconBitmapCache.shared.setImage(image, forKey: key)
562
+ if cacheImage {
563
+ IconBitmapCache.shared.setImage(image, forKey: key)
564
+ }
557
565
 
558
566
  return image
559
567
  }
@@ -569,7 +577,31 @@ class MarkerView: ExpoView {
569
577
  }
570
578
  }
571
579
 
572
- private func refreshChildrenImageInPlace(invalidateChildrenCache: Bool = false) {
580
+ private func currentChildrenAnnotationView() -> MAAnnotationView? {
581
+ if let annotationView,
582
+ let annotation,
583
+ isAnnotationView(annotationView, boundTo: annotation) {
584
+ return annotationView
585
+ }
586
+
587
+ if annotationView != nil {
588
+ annotationView = nil
589
+ }
590
+
591
+ if let animatedAnnotationView,
592
+ let animatedAnnotation,
593
+ isAnnotationView(animatedAnnotationView, boundTo: animatedAnnotation) {
594
+ return animatedAnnotationView
595
+ }
596
+
597
+ if animatedAnnotationView != nil {
598
+ animatedAnnotationView = nil
599
+ }
600
+
601
+ return nil
602
+ }
603
+
604
+ private func refreshChildrenImageInPlace(invalidateChildrenCache: Bool = false, cacheImage: Bool = true) {
573
605
  guard !isRemoving else { return }
574
606
 
575
607
  let refresh = { [weak self] in
@@ -580,7 +612,7 @@ class MarkerView: ExpoView {
580
612
  self.invalidateCurrentChildrenCache()
581
613
  }
582
614
 
583
- guard let targetView = self.annotationView ?? self.animatedAnnotationView else {
615
+ guard let targetView = self.currentChildrenAnnotationView() else {
584
616
  self.refreshAnnotationAppearance(invalidateChildrenCache: invalidateChildrenCache)
585
617
  return
586
618
  }
@@ -589,12 +621,12 @@ class MarkerView: ExpoView {
589
621
  let key = self.childrenCacheKey(for: size)
590
622
  let signature = self.childrenRenderSignature()
591
623
 
592
- if let cached = IconBitmapCache.shared.image(forKey: key) {
624
+ if cacheImage, let cached = IconBitmapCache.shared.image(forKey: key) {
593
625
  self.applyChildrenImage(cached, to: targetView, signature: signature)
594
626
  return
595
627
  }
596
628
 
597
- if let generated = self.createImageFromSubviews(size: size) {
629
+ if let generated = self.createImageFromSubviews(size: size, cacheImage: cacheImage) {
598
630
  self.applyChildrenImage(generated, to: targetView, signature: signature)
599
631
  return
600
632
  }
@@ -611,15 +643,47 @@ class MarkerView: ExpoView {
611
643
  }
612
644
  }
613
645
 
614
- private func scheduleChildrenImageRefresh(invalidateChildrenCache: Bool = false) {
646
+ private func scheduleChildrenImageRefresh(
647
+ invalidateChildrenCache: Bool = false,
648
+ cacheImage: Bool = true,
649
+ delay: TimeInterval = 0.02
650
+ ) {
615
651
  pendingSubviewRefreshTask?.cancel()
616
652
 
617
653
  let task = DispatchWorkItem { [weak self] in
618
- self?.refreshChildrenImageInPlace(invalidateChildrenCache: invalidateChildrenCache)
654
+ self?.refreshChildrenImageInPlace(invalidateChildrenCache: invalidateChildrenCache, cacheImage: cacheImage)
619
655
  }
620
656
 
621
657
  pendingSubviewRefreshTask = task
622
- DispatchQueue.main.asyncAfter(deadline: .now() + 0.02, execute: task)
658
+ DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: task)
659
+ }
660
+
661
+ private func scheduleCacheKeyChildrenImageRefresh() {
662
+ pendingSubviewRefreshTask?.cancel()
663
+ pendingSubviewRefreshTask = nil
664
+ pendingCacheKeyRefreshTask?.cancel()
665
+
666
+ cacheKeyRefreshGeneration += 1
667
+ let generation = cacheKeyRefreshGeneration
668
+
669
+ lastRenderedChildrenSignature = nil
670
+ invalidateCurrentChildrenCache()
671
+
672
+ let uncachedTask = DispatchWorkItem { [weak self] in
673
+ guard let self = self, !self.isRemoving, self.cacheKeyRefreshGeneration == generation else { return }
674
+ self.refreshChildrenImageInPlace(invalidateChildrenCache: true, cacheImage: false)
675
+
676
+ let cachedTask = DispatchWorkItem { [weak self] in
677
+ guard let self = self, !self.isRemoving, self.cacheKeyRefreshGeneration == generation else { return }
678
+ self.refreshChildrenImageInPlace(invalidateChildrenCache: true, cacheImage: true)
679
+ }
680
+
681
+ self.pendingCacheKeyRefreshTask = cachedTask
682
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.08, execute: cachedTask)
683
+ }
684
+
685
+ pendingCacheKeyRefreshTask = uncachedTask
686
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.02, execute: uncachedTask)
623
687
  }
624
688
 
625
689
  private func iconCacheKey(for iconUri: String) -> String {
@@ -792,12 +856,39 @@ class MarkerView: ExpoView {
792
856
  */
793
857
  override func willMove(toSuperview newSuperview: UIView?) {
794
858
  super.willMove(toSuperview: newSuperview)
795
-
796
- // 如果 newSuperview 为 nil,说明视图正在被移除
859
+
797
860
  if newSuperview == nil {
798
- removeAnnotationFromMap()
861
+ scheduleAnnotationRemovalFromMap()
862
+ } else {
863
+ cancelPendingAnnotationRemoval()
864
+ }
865
+ }
866
+
867
+ override func didMoveToSuperview() {
868
+ super.didMoveToSuperview()
869
+
870
+ if superview != nil {
871
+ cancelPendingAnnotationRemoval()
799
872
  }
800
873
  }
874
+
875
+ private func scheduleAnnotationRemovalFromMap() {
876
+ cancelPendingAnnotationRemoval()
877
+
878
+ let task = DispatchWorkItem { [weak self] in
879
+ guard let self = self, self.superview == nil else { return }
880
+ self.pendingAnnotationRemovalTask = nil
881
+ self.removeAnnotationFromMap()
882
+ }
883
+
884
+ pendingAnnotationRemovalTask = task
885
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3, execute: task)
886
+ }
887
+
888
+ private func cancelPendingAnnotationRemoval() {
889
+ pendingAnnotationRemovalTask?.cancel()
890
+ pendingAnnotationRemovalTask = nil
891
+ }
801
892
 
802
893
  /**
803
894
  * 从地图移除标记点
@@ -805,9 +896,11 @@ class MarkerView: ExpoView {
805
896
  private func removeAnnotationFromMap() {
806
897
  guard !isRemoving else { return }
807
898
  isRemoving = true
899
+ cancelPendingAnnotationRemoval()
808
900
  pendingAddTask?.cancel(); pendingAddTask = nil
809
901
  pendingUpdateTask?.cancel(); pendingUpdateTask = nil
810
902
  pendingSubviewRefreshTask?.cancel(); pendingSubviewRefreshTask = nil
903
+ pendingCacheKeyRefreshTask?.cancel(); pendingCacheKeyRefreshTask = nil
811
904
 
812
905
  if Thread.isMainThread {
813
906
  cleanupAnnotationFromMap()
@@ -919,7 +1012,7 @@ class MarkerView: ExpoView {
919
1012
  return
920
1013
  }
921
1014
 
922
- guard let annotationView = annotationView else {
1015
+ guard let annotationView = currentChildrenAnnotationView() else {
923
1016
  mapView.removeAnnotation(annotation)
924
1017
  mapView.addAnnotation(annotation)
925
1018
  return
@@ -1353,6 +1446,8 @@ class MarkerView: ExpoView {
1353
1446
  pendingAddTask?.cancel()
1354
1447
  pendingUpdateTask?.cancel()
1355
1448
  pendingSubviewRefreshTask?.cancel()
1449
+ pendingCacheKeyRefreshTask?.cancel()
1450
+ pendingAnnotationRemovalTask?.cancel()
1356
1451
 
1357
1452
  if Thread.isMainThread {
1358
1453
  cleanupAnnotationFromMap()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-gaode-map",
3
- "version": "2.2.39-next.0",
3
+ "version": "2.2.40-next.0",
4
4
  "description": "Expo Modules AMap (Gaode Map) stack for Expo/React Native: Config Plugin, New Architecture support, maps, location, search, offline maps, and react-native-amap3d migration guidance.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",