expo-gaode-map 2.2.29 → 2.2.30-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.
- package/android/src/main/java/expo/modules/gaodemap/ExpoGaodeMapView.kt +65 -6
- package/android/src/main/java/expo/modules/gaodemap/overlays/MarkerView.kt +278 -42
- package/build/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapModule.js +22 -3
- package/build/ExpoGaodeMapModule.js.map +1 -1
- package/build/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/ExpoGaodeMapView.js +36 -18
- package/build/ExpoGaodeMapView.js.map +1 -1
- package/build/components/overlays/Marker.d.ts.map +1 -1
- package/build/components/overlays/Marker.js +46 -3
- package/build/components/overlays/Marker.js.map +1 -1
- package/build/types/overlays.types.d.ts +6 -2
- package/build/types/overlays.types.d.ts.map +1 -1
- package/build/types/overlays.types.js.map +1 -1
- package/ios/overlays/MarkerView.swift +167 -53
- package/package.json +1 -1
|
@@ -32,6 +32,10 @@ import androidx.core.graphics.withTranslation
|
|
|
32
32
|
@SuppressLint("ViewConstructor")
|
|
33
33
|
class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(context, appContext) {
|
|
34
34
|
|
|
35
|
+
init {
|
|
36
|
+
orientation = VERTICAL
|
|
37
|
+
}
|
|
38
|
+
|
|
35
39
|
/**
|
|
36
40
|
* 拦截 React Native 的 ViewManager 操作
|
|
37
41
|
* 重写 requestLayout 防止在移除视图时触发布局异常
|
|
@@ -44,6 +48,63 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
44
48
|
}
|
|
45
49
|
}
|
|
46
50
|
|
|
51
|
+
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
|
52
|
+
val measuredWidth = View.MeasureSpec.getSize(widthMeasureSpec)
|
|
53
|
+
val measuredHeight = View.MeasureSpec.getSize(heightMeasureSpec)
|
|
54
|
+
|
|
55
|
+
setMeasuredDimension(measuredWidth, measuredHeight)
|
|
56
|
+
|
|
57
|
+
for (i in 0 until childCount) {
|
|
58
|
+
val child = getChildAt(i) ?: continue
|
|
59
|
+
if (child.visibility == View.GONE) {
|
|
60
|
+
continue
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (child === mapView) {
|
|
64
|
+
val childWidthSpec = View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.EXACTLY)
|
|
65
|
+
val childHeightSpec = View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.EXACTLY)
|
|
66
|
+
child.measure(childWidthSpec, childHeightSpec)
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
val lp = child.layoutParams
|
|
71
|
+
val childWidthSpec = when {
|
|
72
|
+
lp?.width != null && lp.width > 0 ->
|
|
73
|
+
View.MeasureSpec.makeMeasureSpec(lp.width, View.MeasureSpec.EXACTLY)
|
|
74
|
+
else ->
|
|
75
|
+
View.MeasureSpec.makeMeasureSpec(measuredWidth, View.MeasureSpec.AT_MOST)
|
|
76
|
+
}
|
|
77
|
+
val childHeightSpec = when {
|
|
78
|
+
lp?.height != null && lp.height > 0 ->
|
|
79
|
+
View.MeasureSpec.makeMeasureSpec(lp.height, View.MeasureSpec.EXACTLY)
|
|
80
|
+
else ->
|
|
81
|
+
View.MeasureSpec.makeMeasureSpec(measuredHeight, View.MeasureSpec.AT_MOST)
|
|
82
|
+
}
|
|
83
|
+
child.measure(childWidthSpec, childHeightSpec)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
88
|
+
val width = right - left
|
|
89
|
+
val height = bottom - top
|
|
90
|
+
|
|
91
|
+
for (i in 0 until childCount) {
|
|
92
|
+
val child = getChildAt(i) ?: continue
|
|
93
|
+
if (child.visibility == View.GONE) {
|
|
94
|
+
continue
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (child === mapView) {
|
|
98
|
+
child.layout(0, 0, width, height)
|
|
99
|
+
continue
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
val childWidth = child.measuredWidth
|
|
103
|
+
val childHeight = child.measuredHeight
|
|
104
|
+
child.layout(0, 0, childWidth, childHeight)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
47
108
|
// Props 存储
|
|
48
109
|
/** 地图类型 */
|
|
49
110
|
internal var mapType: Int = 0
|
|
@@ -617,9 +678,10 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
617
678
|
override fun addView(child: View?, index: Int) {
|
|
618
679
|
if (child is MarkerView) {
|
|
619
680
|
child.setMap(aMap)
|
|
620
|
-
// MarkerView
|
|
621
|
-
//
|
|
622
|
-
|
|
681
|
+
// MarkerView 需要保留可测量尺寸,否则 Android 无法正确处理
|
|
682
|
+
// Text / View 的 maxWidth 等布局约束,最终会被测成整行宽度。
|
|
683
|
+
// 这里保留 WRAP_CONTENT,并继续移到屏幕外,避免影响可见布局。
|
|
684
|
+
val params = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
|
|
623
685
|
child.layoutParams = params
|
|
624
686
|
child.translationX = -10000f // 移到屏幕外
|
|
625
687
|
child.translationY = -10000f
|
|
@@ -729,7 +791,4 @@ class ExpoGaodeMapView(context: Context, appContext: AppContext) : ExpoView(cont
|
|
|
729
791
|
return false
|
|
730
792
|
}
|
|
731
793
|
|
|
732
|
-
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
|
|
733
|
-
super.onLayout(changed, left, top, right, bottom)
|
|
734
|
-
}
|
|
735
794
|
}
|
|
@@ -5,6 +5,8 @@ import android.content.Context
|
|
|
5
5
|
import android.graphics.Bitmap
|
|
6
6
|
import android.graphics.BitmapFactory
|
|
7
7
|
import android.graphics.Canvas
|
|
8
|
+
import android.graphics.Color
|
|
9
|
+
import android.graphics.Rect
|
|
8
10
|
|
|
9
11
|
import android.os.Handler
|
|
10
12
|
import android.os.Looper
|
|
@@ -41,6 +43,8 @@ import expo.modules.gaodemap.companion.BitmapDescriptorCache
|
|
|
41
43
|
import expo.modules.gaodemap.companion.IconBitmapCache
|
|
42
44
|
import expo.modules.gaodemap.utils.GeometryUtils
|
|
43
45
|
import kotlin.text.StringBuilder
|
|
46
|
+
import kotlin.math.max
|
|
47
|
+
import kotlin.math.min
|
|
44
48
|
|
|
45
49
|
import java.util.concurrent.CountDownLatch
|
|
46
50
|
import java.util.concurrent.TimeUnit
|
|
@@ -53,6 +57,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
53
57
|
// 不可交互,通过父视图定位到屏幕外
|
|
54
58
|
isClickable = false
|
|
55
59
|
isFocusable = false
|
|
60
|
+
isBaselineAligned = false
|
|
56
61
|
// 设置为水平方向(默认),让子视图自然布局
|
|
57
62
|
orientation = HORIZONTAL
|
|
58
63
|
}
|
|
@@ -118,11 +123,98 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
118
123
|
}
|
|
119
124
|
}
|
|
120
125
|
|
|
121
|
-
|
|
126
|
+
if (childCount == 0) {
|
|
122
127
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
|
123
|
-
|
|
124
|
-
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
val parentWidthSize = MeasureSpec.getSize(widthMeasureSpec)
|
|
132
|
+
val parentHeightSize = MeasureSpec.getSize(heightMeasureSpec)
|
|
133
|
+
val fallbackWidthSize = resolveExplicitMeasureSize(parentWidthSize, true)
|
|
134
|
+
val fallbackHeightSize = resolveExplicitMeasureSize(parentHeightSize, false)
|
|
135
|
+
|
|
136
|
+
val contentWidthSpec = when {
|
|
137
|
+
customViewWidth > 0 -> MeasureSpec.makeMeasureSpec(customViewWidth, MeasureSpec.EXACTLY)
|
|
138
|
+
fallbackWidthSize > 0 -> MeasureSpec.makeMeasureSpec(fallbackWidthSize, MeasureSpec.AT_MOST)
|
|
139
|
+
else -> MeasureSpec.makeMeasureSpec(1, MeasureSpec.EXACTLY)
|
|
140
|
+
}
|
|
141
|
+
val contentHeightSpec = when {
|
|
142
|
+
customViewHeight > 0 -> MeasureSpec.makeMeasureSpec(customViewHeight, MeasureSpec.EXACTLY)
|
|
143
|
+
fallbackHeightSize > 0 -> MeasureSpec.makeMeasureSpec(fallbackHeightSize, MeasureSpec.AT_MOST)
|
|
144
|
+
else -> MeasureSpec.makeMeasureSpec(1, MeasureSpec.EXACTLY)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
var measuredContentWidth = 0
|
|
148
|
+
var measuredContentHeight = 0
|
|
149
|
+
|
|
150
|
+
for (i in 0 until childCount) {
|
|
151
|
+
val child = getChildAt(i)
|
|
152
|
+
val lp = child.layoutParams as? LayoutParams
|
|
153
|
+
?: LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
|
|
154
|
+
|
|
155
|
+
val childWidthSpec = getChildMeasureSpec(
|
|
156
|
+
contentWidthSpec,
|
|
157
|
+
paddingLeft + paddingRight,
|
|
158
|
+
lp.width
|
|
159
|
+
)
|
|
160
|
+
val childHeightSpec = getChildMeasureSpec(
|
|
161
|
+
contentHeightSpec,
|
|
162
|
+
paddingTop + paddingBottom,
|
|
163
|
+
lp.height
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
child.measure(childWidthSpec, childHeightSpec)
|
|
167
|
+
val childBounds = computeContentBounds(child)
|
|
168
|
+
measuredContentWidth = max(measuredContentWidth, childBounds?.width() ?: child.measuredWidth)
|
|
169
|
+
measuredContentHeight = max(measuredContentHeight, childBounds?.height() ?: child.measuredHeight)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
val desiredWidth = if (customViewWidth > 0) {
|
|
173
|
+
customViewWidth
|
|
174
|
+
} else {
|
|
175
|
+
measuredContentWidth + paddingLeft + paddingRight
|
|
176
|
+
}
|
|
177
|
+
val desiredHeight = if (customViewHeight > 0) {
|
|
178
|
+
customViewHeight
|
|
179
|
+
} else {
|
|
180
|
+
measuredContentHeight + paddingTop + paddingBottom
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
val finalWidth = if (parentWidthSize > 0) min(desiredWidth, parentWidthSize) else desiredWidth
|
|
184
|
+
val finalHeight = if (parentHeightSize > 0) min(desiredHeight, parentHeightSize) else desiredHeight
|
|
185
|
+
|
|
186
|
+
setMeasuredDimension(
|
|
187
|
+
max(finalWidth, suggestedMinimumWidth),
|
|
188
|
+
max(finalHeight, suggestedMinimumHeight)
|
|
189
|
+
)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
private fun resolveExplicitMeasureSize(parentSize: Int, isWidth: Boolean): Int {
|
|
193
|
+
if (parentSize > 0) {
|
|
194
|
+
return parentSize
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
val parentView = parent as? View
|
|
198
|
+
val parentMeasuredSize = if (isWidth) {
|
|
199
|
+
parentView?.measuredWidth ?: 0
|
|
200
|
+
} else {
|
|
201
|
+
parentView?.measuredHeight ?: 0
|
|
202
|
+
}
|
|
203
|
+
if (parentMeasuredSize > 0) {
|
|
204
|
+
return parentMeasuredSize
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
val parentLayoutSize = if (isWidth) {
|
|
208
|
+
parentView?.width ?: 0
|
|
209
|
+
} else {
|
|
210
|
+
parentView?.height ?: 0
|
|
211
|
+
}
|
|
212
|
+
if (parentLayoutSize > 0) {
|
|
213
|
+
return parentLayoutSize
|
|
125
214
|
}
|
|
215
|
+
|
|
216
|
+
val displayMetrics = context.resources.displayMetrics
|
|
217
|
+
return if (isWidth) displayMetrics.widthPixels else displayMetrics.heightPixels
|
|
126
218
|
}
|
|
127
219
|
|
|
128
220
|
private val onMarkerPress by EventDispatcher()
|
|
@@ -141,6 +233,8 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
141
233
|
private var customViewHeight: Int = 0 // 用于自定义视图(children)的高度
|
|
142
234
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
143
235
|
private var isRemoving = false // 标记是否正在被移除
|
|
236
|
+
private var pendingMarkerIconUpdate: Runnable? = null
|
|
237
|
+
private var lastAppliedCustomMarkerKey: String? = null
|
|
144
238
|
|
|
145
239
|
// 缓存属性,在 marker 创建前保存
|
|
146
240
|
private var pendingTitle: String? = null
|
|
@@ -789,8 +883,10 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
789
883
|
val keyPart = cacheKey ?: computeViewFingerprint(this)
|
|
790
884
|
|
|
791
885
|
val measuredChild = if (isNotEmpty()) getChildAt(0) else null
|
|
792
|
-
val
|
|
793
|
-
val
|
|
886
|
+
val contentView = resolveRenderableContentView(measuredChild)
|
|
887
|
+
val contentBounds = computeContentBounds(measuredChild)
|
|
888
|
+
val measuredWidth = contentBounds?.width() ?: contentView?.measuredWidth ?: measuredChild?.measuredWidth ?: 0
|
|
889
|
+
val measuredHeight = contentBounds?.height() ?: contentView?.measuredHeight ?: measuredChild?.measuredHeight ?: 0
|
|
794
890
|
|
|
795
891
|
val finalWidth = if (measuredWidth > 0) measuredWidth else (if (customViewWidth > 0) customViewWidth else 0)
|
|
796
892
|
val finalHeight = if (measuredHeight > 0) measuredHeight else (if (customViewHeight > 0) customViewHeight else 0)
|
|
@@ -873,13 +969,85 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
873
969
|
childView.isDrawingCacheEnabled = false
|
|
874
970
|
childView.destroyDrawingCache()
|
|
875
971
|
|
|
876
|
-
|
|
972
|
+
val shouldTrimTransparentPadding = customViewWidth <= 0 && customViewHeight <= 0
|
|
973
|
+
return if (shouldTrimTransparentPadding) trimTransparentPadding(bitmap) else bitmap
|
|
877
974
|
} catch (_: Exception) {
|
|
878
975
|
// 遇到异常时返回 null,让上层使用默认图标
|
|
879
976
|
return null
|
|
880
977
|
}
|
|
881
978
|
}
|
|
882
979
|
|
|
980
|
+
private fun trimTransparentPadding(bitmap: Bitmap): Bitmap {
|
|
981
|
+
if (bitmap.width <= 1 || bitmap.height <= 1) {
|
|
982
|
+
return bitmap
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (hasOpaquePixelsOnAllBitmapEdges(bitmap)) {
|
|
986
|
+
return bitmap
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
var minX = bitmap.width
|
|
990
|
+
var minY = bitmap.height
|
|
991
|
+
var maxX = -1
|
|
992
|
+
var maxY = -1
|
|
993
|
+
|
|
994
|
+
for (y in 0 until bitmap.height) {
|
|
995
|
+
for (x in 0 until bitmap.width) {
|
|
996
|
+
if (Color.alpha(bitmap.getPixel(x, y)) != 0) {
|
|
997
|
+
if (x < minX) minX = x
|
|
998
|
+
if (y < minY) minY = y
|
|
999
|
+
if (x > maxX) maxX = x
|
|
1000
|
+
if (y > maxY) maxY = y
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
if (maxX < minX || maxY < minY) {
|
|
1006
|
+
return bitmap
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
val trimmedWidth = maxX - minX + 1
|
|
1010
|
+
val trimmedHeight = maxY - minY + 1
|
|
1011
|
+
if (trimmedWidth == bitmap.width && trimmedHeight == bitmap.height) {
|
|
1012
|
+
return bitmap
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
return Bitmap.createBitmap(bitmap, minX, minY, trimmedWidth, trimmedHeight)
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
private fun hasOpaquePixelsOnAllBitmapEdges(bitmap: Bitmap): Boolean {
|
|
1019
|
+
var topEdgeHasPixel = false
|
|
1020
|
+
var bottomEdgeHasPixel = false
|
|
1021
|
+
var leftEdgeHasPixel = false
|
|
1022
|
+
var rightEdgeHasPixel = false
|
|
1023
|
+
|
|
1024
|
+
for (x in 0 until bitmap.width) {
|
|
1025
|
+
if (!topEdgeHasPixel && Color.alpha(bitmap.getPixel(x, 0)) != 0) {
|
|
1026
|
+
topEdgeHasPixel = true
|
|
1027
|
+
}
|
|
1028
|
+
if (!bottomEdgeHasPixel && Color.alpha(bitmap.getPixel(x, bitmap.height - 1)) != 0) {
|
|
1029
|
+
bottomEdgeHasPixel = true
|
|
1030
|
+
}
|
|
1031
|
+
if (topEdgeHasPixel && bottomEdgeHasPixel) {
|
|
1032
|
+
break
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
for (y in 0 until bitmap.height) {
|
|
1037
|
+
if (!leftEdgeHasPixel && Color.alpha(bitmap.getPixel(0, y)) != 0) {
|
|
1038
|
+
leftEdgeHasPixel = true
|
|
1039
|
+
}
|
|
1040
|
+
if (!rightEdgeHasPixel && Color.alpha(bitmap.getPixel(bitmap.width - 1, y)) != 0) {
|
|
1041
|
+
rightEdgeHasPixel = true
|
|
1042
|
+
}
|
|
1043
|
+
if (leftEdgeHasPixel && rightEdgeHasPixel) {
|
|
1044
|
+
break
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
return topEdgeHasPixel && bottomEdgeHasPixel && leftEdgeHasPixel && rightEdgeHasPixel
|
|
1049
|
+
}
|
|
1050
|
+
|
|
883
1051
|
/**
|
|
884
1052
|
* 更新 marker 图标
|
|
885
1053
|
*/
|
|
@@ -887,6 +1055,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
887
1055
|
if (isEmpty()) {
|
|
888
1056
|
// 如果确实为空(没有子视图),恢复默认样式
|
|
889
1057
|
marker?.setIcon(BitmapDescriptorFactory.defaultMarker())
|
|
1058
|
+
lastAppliedCustomMarkerKey = null
|
|
890
1059
|
// 恢复默认锚点(底部中心),除非用户指定了锚点
|
|
891
1060
|
val anchorX = pendingAnchor?.first ?: 0.5f
|
|
892
1061
|
val anchorY = pendingAnchor?.second ?: 1.0f
|
|
@@ -898,18 +1067,27 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
898
1067
|
// 构建缓存 key(优先 JS 端 cacheKey)
|
|
899
1068
|
val keyPart = cacheKey ?: computeViewFingerprint(this)
|
|
900
1069
|
val child = getChildAt(0)
|
|
901
|
-
val
|
|
902
|
-
val
|
|
1070
|
+
val contentView = resolveRenderableContentView(child)
|
|
1071
|
+
val contentBounds = computeContentBounds(child)
|
|
1072
|
+
val measuredWidth = contentBounds?.width() ?: contentView?.measuredWidth ?: child?.measuredWidth ?: customViewWidth
|
|
1073
|
+
val measuredHeight = contentBounds?.height() ?: contentView?.measuredHeight ?: child?.measuredHeight ?: customViewHeight
|
|
903
1074
|
val fullCacheKey = "$keyPart|${measuredWidth}x${measuredHeight}"
|
|
904
1075
|
|
|
905
1076
|
// 确定锚点:优先使用用户指定的 pendingAnchor,否则对于自定义 View 使用中心点 (0.5, 0.5)
|
|
906
1077
|
val anchorX = pendingAnchor?.first ?: 0.5f
|
|
907
1078
|
val anchorY = pendingAnchor?.second ?: 0.5f
|
|
908
1079
|
|
|
1080
|
+
if (fullCacheKey == lastAppliedCustomMarkerKey) {
|
|
1081
|
+
marker?.setAnchor(anchorX, anchorY)
|
|
1082
|
+
marker?.let { showMarker(it) }
|
|
1083
|
+
return
|
|
1084
|
+
}
|
|
1085
|
+
|
|
909
1086
|
// 1) 尝试 BitmapDescriptor 缓存
|
|
910
1087
|
BitmapDescriptorCache.get(fullCacheKey)?.let { it ->
|
|
911
1088
|
marker?.setIcon(it)
|
|
912
1089
|
marker?.setAnchor(anchorX, anchorY)
|
|
1090
|
+
lastAppliedCustomMarkerKey = fullCacheKey
|
|
913
1091
|
marker?.let { showMarker(it) }
|
|
914
1092
|
return
|
|
915
1093
|
}
|
|
@@ -933,9 +1111,31 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
933
1111
|
// 设置到 Marker
|
|
934
1112
|
marker?.setIcon(descriptor)
|
|
935
1113
|
marker?.setAnchor(anchorX, anchorY)
|
|
1114
|
+
lastAppliedCustomMarkerKey = fullCacheKey
|
|
936
1115
|
marker?.let { showMarker(it) }
|
|
937
1116
|
}
|
|
938
1117
|
|
|
1118
|
+
private fun scheduleMarkerIconUpdate(delayMs: Long = 16L) {
|
|
1119
|
+
if (isRemoving || marker == null || isEmpty()) {
|
|
1120
|
+
return
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
pendingMarkerIconUpdate?.let { mainHandler.removeCallbacks(it) }
|
|
1124
|
+
val task = Runnable {
|
|
1125
|
+
pendingMarkerIconUpdate = null
|
|
1126
|
+
if (!isRemoving && marker != null && isNotEmpty()) {
|
|
1127
|
+
updateMarkerIcon()
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
pendingMarkerIconUpdate = task
|
|
1131
|
+
|
|
1132
|
+
if (delayMs <= 0L) {
|
|
1133
|
+
mainHandler.post(task)
|
|
1134
|
+
} else {
|
|
1135
|
+
mainHandler.postDelayed(task, delayMs)
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
|
|
939
1139
|
|
|
940
1140
|
|
|
941
1141
|
override fun removeView(child: View?) {
|
|
@@ -957,11 +1157,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
957
1157
|
super.removeViewAt(index)
|
|
958
1158
|
// 只在还有子视图时更新图标
|
|
959
1159
|
if (!isRemoving && childCount > 1 && marker != null) {
|
|
960
|
-
|
|
961
|
-
if (!isRemoving && marker != null && isNotEmpty()) {
|
|
962
|
-
updateMarkerIcon()
|
|
963
|
-
}
|
|
964
|
-
}, 50)
|
|
1160
|
+
scheduleMarkerIconUpdate(50)
|
|
965
1161
|
}
|
|
966
1162
|
// 如果最后一个子视图被移除,什么都不做
|
|
967
1163
|
// 让 onDetachedFromWindow 处理完整的清理
|
|
@@ -970,35 +1166,82 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
970
1166
|
// 忽略异常
|
|
971
1167
|
}
|
|
972
1168
|
}
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1169
|
+
private fun resolveRenderableContentView(view: View?): View? {
|
|
1170
|
+
var current = view ?: return null
|
|
1171
|
+
|
|
1172
|
+
while (current is ViewGroup && current.childCount == 1) {
|
|
1173
|
+
val next = current.getChildAt(0) ?: break
|
|
1174
|
+
current = next
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
return current
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
private fun computeContentBounds(view: View?): Rect? {
|
|
1181
|
+
view ?: return null
|
|
1182
|
+
if (view.visibility != View.VISIBLE) return null
|
|
1183
|
+
|
|
1184
|
+
var resolvedBounds: Rect? = null
|
|
1185
|
+
|
|
1186
|
+
if (view is ViewGroup && view.childCount > 0) {
|
|
1187
|
+
for (i in 0 until view.childCount) {
|
|
1188
|
+
val child = view.getChildAt(i) ?: continue
|
|
1189
|
+
val childBounds = computeContentBounds(child) ?: continue
|
|
1190
|
+
val shiftedBounds = Rect(childBounds)
|
|
1191
|
+
shiftedBounds.offset(child.left, child.top)
|
|
1192
|
+
resolvedBounds = if (resolvedBounds == null) {
|
|
1193
|
+
shiftedBounds
|
|
1194
|
+
} else {
|
|
1195
|
+
Rect(resolvedBounds).apply { union(shiftedBounds) }
|
|
988
1196
|
}
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
val hasOwnVisualBounds =
|
|
1201
|
+
view.background != null ||
|
|
1202
|
+
view.paddingLeft != 0 ||
|
|
1203
|
+
view.paddingTop != 0 ||
|
|
1204
|
+
view.paddingRight != 0 ||
|
|
1205
|
+
view.paddingBottom != 0 ||
|
|
1206
|
+
view !is ViewGroup
|
|
1207
|
+
|
|
1208
|
+
val ownWidth = view.measuredWidth.takeIf { it > 0 } ?: view.width
|
|
1209
|
+
val ownHeight = view.measuredHeight.takeIf { it > 0 } ?: view.height
|
|
1210
|
+
|
|
1211
|
+
if (hasOwnVisualBounds && ownWidth > 0 && ownHeight > 0) {
|
|
1212
|
+
val ownBounds = Rect(0, 0, ownWidth, ownHeight)
|
|
1213
|
+
resolvedBounds = if (resolvedBounds == null) {
|
|
1214
|
+
ownBounds
|
|
1215
|
+
} else {
|
|
1216
|
+
Rect(resolvedBounds).apply { union(ownBounds) }
|
|
1217
|
+
}
|
|
989
1218
|
}
|
|
1219
|
+
|
|
1220
|
+
return resolvedBounds
|
|
990
1221
|
}
|
|
991
1222
|
|
|
992
1223
|
|
|
993
1224
|
override fun addView(child: View?, index: Int, params: android.view.ViewGroup.LayoutParams?) {
|
|
994
1225
|
// 🔑 关键修复:记录添加前的子视图数量
|
|
995
1226
|
val childCountBefore = childCount
|
|
1227
|
+
|
|
1228
|
+
val sourceWidth = when {
|
|
1229
|
+
customViewWidth > 0 -> customViewWidth
|
|
1230
|
+
params?.width != null && params.width > 0 -> params.width
|
|
1231
|
+
else -> LayoutParams.WRAP_CONTENT
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
val sourceHeight = when {
|
|
1235
|
+
customViewHeight > 0 -> customViewHeight
|
|
1236
|
+
params?.height != null && params.height > 0 -> params.height
|
|
1237
|
+
else -> LayoutParams.WRAP_CONTENT
|
|
1238
|
+
}
|
|
996
1239
|
|
|
997
1240
|
val finalParams = LayoutParams(
|
|
998
|
-
|
|
999
|
-
|
|
1241
|
+
sourceWidth,
|
|
1242
|
+
sourceHeight
|
|
1000
1243
|
)
|
|
1001
|
-
|
|
1244
|
+
|
|
1002
1245
|
super.addView(child, index, finalParams)
|
|
1003
1246
|
|
|
1004
1247
|
child?.let {
|
|
@@ -1009,17 +1252,12 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
1009
1252
|
childParams?.height ?: LayoutParams.WRAP_CONTENT
|
|
1010
1253
|
)
|
|
1011
1254
|
}
|
|
1012
|
-
fixChildLayoutParams(it)
|
|
1013
1255
|
}
|
|
1014
1256
|
|
|
1015
1257
|
// 🔑 修复:需要延迟更新图标,等待 children 完成布局
|
|
1016
1258
|
// 原因:立即更新会在 children 还未完成测量/布局时就渲染,导致内容为空
|
|
1017
1259
|
if (!isRemoving && marker != null && childCount > childCountBefore) {
|
|
1018
|
-
|
|
1019
|
-
if (!isRemoving && marker != null && isNotEmpty()) {
|
|
1020
|
-
updateMarkerIcon()
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1260
|
+
scheduleMarkerIconUpdate()
|
|
1023
1261
|
}
|
|
1024
1262
|
}
|
|
1025
1263
|
|
|
@@ -1028,11 +1266,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
1028
1266
|
// 🔑 修复:布局完成后延迟更新图标
|
|
1029
1267
|
// 即使 changed 为 false,只要有内容,也应该检查是否需要更新(例如子 View 尺寸变化但 MarkerView 没变)
|
|
1030
1268
|
if (!isRemoving && isNotEmpty() && marker != null) {
|
|
1031
|
-
|
|
1032
|
-
if (!isRemoving && marker != null && isNotEmpty()) {
|
|
1033
|
-
updateMarkerIcon()
|
|
1034
|
-
}
|
|
1035
|
-
}
|
|
1269
|
+
scheduleMarkerIconUpdate()
|
|
1036
1270
|
}
|
|
1037
1271
|
}
|
|
1038
1272
|
|
|
@@ -1239,6 +1473,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
1239
1473
|
private fun stopSmoothMove() {
|
|
1240
1474
|
smoothMoveMarker?.stopMove()
|
|
1241
1475
|
smoothMoveMarker?.setVisible(false)
|
|
1476
|
+
lastAppliedCustomMarkerKey = null
|
|
1242
1477
|
marker?.let { showMarker(it) }
|
|
1243
1478
|
}
|
|
1244
1479
|
|
|
@@ -1264,6 +1499,7 @@ class MarkerView(context: Context, appContext: AppContext) : ExpoView(context, a
|
|
|
1264
1499
|
// 🔑 关键修复:使用 post 延迟检查
|
|
1265
1500
|
// 清理所有延迟任务
|
|
1266
1501
|
mainHandler.removeCallbacksAndMessages(null)
|
|
1502
|
+
pendingMarkerIconUpdate = null
|
|
1267
1503
|
|
|
1268
1504
|
// 延迟检查 parent 状态
|
|
1269
1505
|
mainHandler.post {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ExpoGaodeMapModule.d.ts","sourceRoot":"","sources":["../src/ExpoGaodeMapModule.ts"],"names":[],"mappings":"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"}
|
|
@@ -741,16 +741,35 @@ const helperMethods = {
|
|
|
741
741
|
try {
|
|
742
742
|
const normalizedPoint = normalizeLatLng(point);
|
|
743
743
|
let normalizedPolygons;
|
|
744
|
+
let ringToPolygonIndex = null;
|
|
744
745
|
// 处理三维数组 (LatLngPoint[][][]) 和二维数组 (LatLngPoint[][])
|
|
745
746
|
if (Array.isArray(polygons[0]) && Array.isArray(polygons[0][0])) {
|
|
746
747
|
// LatLngPoint[][][] -> 扁平化为 LatLngPoint[][] 用于 C++ 遍历
|
|
747
|
-
|
|
748
|
+
// 同时记录每个 Ring 对应的原始多边形索引
|
|
749
|
+
normalizedPolygons = [];
|
|
750
|
+
ringToPolygonIndex = [];
|
|
751
|
+
polygons.forEach((polygonRings, index) => {
|
|
752
|
+
polygonRings.forEach((ring) => {
|
|
753
|
+
normalizedPolygons.push(ring);
|
|
754
|
+
ringToPolygonIndex.push(index);
|
|
755
|
+
});
|
|
756
|
+
});
|
|
748
757
|
}
|
|
749
758
|
else {
|
|
750
759
|
normalizedPolygons = polygons;
|
|
751
760
|
}
|
|
752
|
-
const processedPolygons = normalizedPolygons.map(p => normalizeLatLngList(p));
|
|
753
|
-
|
|
761
|
+
const processedPolygons = normalizedPolygons.map((p) => normalizeLatLngList(p));
|
|
762
|
+
const resultIndex = nativeModule.findPointInPolygons(normalizedPoint, processedPolygons);
|
|
763
|
+
// 如果未命中,返回 -1
|
|
764
|
+
if (resultIndex === -1) {
|
|
765
|
+
return -1;
|
|
766
|
+
}
|
|
767
|
+
// 如果存在映射关系(带孔多边形),将 Ring 索引映射回 Polygon 索引
|
|
768
|
+
if (ringToPolygonIndex) {
|
|
769
|
+
return ringToPolygonIndex[resultIndex];
|
|
770
|
+
}
|
|
771
|
+
// 简单多边形直接返回索引
|
|
772
|
+
return resultIndex;
|
|
754
773
|
}
|
|
755
774
|
catch (error) {
|
|
756
775
|
ErrorLogger.warn('findPointInPolygons 失败', { point, error });
|