expo-gaode-map-navigation 1.1.4 → 1.1.5-next.1
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/README.md +213 -73
- package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviView.kt +414 -26
- package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviViewModule.kt +44 -3
- package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNavigationModule.kt +2 -0
- package/build/ExpoGaodeMapNaviView.js +2 -3
- package/build/map/ExpoGaodeMapModule.js +4 -6
- package/build/map/index.d.ts +0 -2
- package/build/map/index.js +0 -1
- package/build/map/types/overlays.types.d.ts +1 -1
- package/build/map/utils/EventManager.js +1 -1
- package/build/types/naviview.types.d.ts +22 -20
- package/ios/ExpoGaodeMapNaviView.swift +87 -3
- package/ios/ExpoGaodeMapNaviViewModule.swift +2 -2
- package/ios/map/modules/LocationManager.swift +9 -1
- package/package.json +30 -33
|
@@ -4,16 +4,20 @@ import android.annotation.SuppressLint
|
|
|
4
4
|
import android.content.Context
|
|
5
5
|
import android.os.Bundle
|
|
6
6
|
import android.util.Log
|
|
7
|
+
import android.view.View
|
|
8
|
+
import android.view.ViewGroup
|
|
7
9
|
import com.amap.api.navi.AMapNavi
|
|
8
10
|
import com.amap.api.navi.AMapNaviListener
|
|
9
11
|
import com.amap.api.navi.AMapNaviView
|
|
10
12
|
import com.amap.api.navi.AMapNaviViewListener
|
|
11
13
|
import com.amap.api.navi.AMapNaviViewOptions
|
|
14
|
+
import com.amap.api.navi.enums.MapStyle
|
|
12
15
|
import com.amap.api.navi.enums.NaviType
|
|
13
16
|
import com.amap.api.navi.model.*
|
|
14
17
|
import expo.modules.kotlin.AppContext
|
|
15
18
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
16
19
|
import expo.modules.kotlin.views.ExpoView
|
|
20
|
+
import java.util.IdentityHashMap
|
|
17
21
|
|
|
18
22
|
@SuppressLint("ViewConstructor")
|
|
19
23
|
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
|
|
@@ -38,11 +42,38 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
38
42
|
internal var showCamera: Boolean = true
|
|
39
43
|
internal var naviType: Int = NaviType.GPS
|
|
40
44
|
internal var enableVoice: Boolean = true
|
|
41
|
-
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
internal var androidStatusBarPaddingTopDp: Double? = null
|
|
48
|
+
|
|
49
|
+
internal var showUIElements: Boolean = true
|
|
50
|
+
internal var androidTrafficBarEnabled: Boolean = true
|
|
51
|
+
internal var isRouteListButtonShow: Boolean = true
|
|
52
|
+
internal var isTrafficLayerEnabled: Boolean = true
|
|
53
|
+
internal var autoChangeZoom : Boolean = true
|
|
54
|
+
internal var autoLockCar: Boolean = true
|
|
55
|
+
internal var isTrafficLine: Boolean = true
|
|
56
|
+
internal var isRealCrossDisplayShow : Boolean = true
|
|
57
|
+
internal var isNaviArrowVisible : Boolean = true
|
|
58
|
+
internal var isAfterRouteAutoGray: Boolean = false
|
|
59
|
+
internal var isVectorLineShow: Boolean = true
|
|
60
|
+
internal var isNaviTravelView : Boolean = false
|
|
61
|
+
internal var isCompassEnabled: Boolean = true
|
|
42
62
|
private val naviView: AMapNaviView = AMapNaviView(context)
|
|
43
63
|
private var aMapNavi: AMapNavi? = null
|
|
44
64
|
private var startCoordinate: NaviLatLng? = null
|
|
45
65
|
private var endCoordinate: NaviLatLng? = null
|
|
66
|
+
|
|
67
|
+
private var lastAppliedTopPaddingPx: Int? = null
|
|
68
|
+
|
|
69
|
+
private var topInsetPx: Int = 0
|
|
70
|
+
private var overlayHooked: Boolean = false
|
|
71
|
+
private val overlayStates = IdentityHashMap<View, OverlayState>()
|
|
72
|
+
|
|
73
|
+
private data class OverlayState(
|
|
74
|
+
val translationY: Float,
|
|
75
|
+
val paddingTop: Int
|
|
76
|
+
)
|
|
46
77
|
|
|
47
78
|
// 导航监听器
|
|
48
79
|
@Suppress("DEPRECATION", "OVERRIDE_DEPRECATION")
|
|
@@ -270,7 +301,18 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
270
301
|
try {
|
|
271
302
|
// 初始化导航视图
|
|
272
303
|
naviView.onCreate(Bundle())
|
|
304
|
+
naviView.layoutParams = android.widget.FrameLayout.LayoutParams(
|
|
305
|
+
android.widget.FrameLayout.LayoutParams.MATCH_PARENT,
|
|
306
|
+
android.widget.FrameLayout.LayoutParams.MATCH_PARENT
|
|
307
|
+
)
|
|
273
308
|
addView(naviView)
|
|
309
|
+
|
|
310
|
+
clipChildren = false
|
|
311
|
+
clipToPadding = false
|
|
312
|
+
naviView.clipChildren = false
|
|
313
|
+
naviView.clipToPadding = false
|
|
314
|
+
|
|
315
|
+
ensureOverlayInsetHook()
|
|
274
316
|
|
|
275
317
|
// 使用单例获取导航实例
|
|
276
318
|
aMapNavi = AMapNavi.getInstance(context.applicationContext)
|
|
@@ -278,27 +320,28 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
278
320
|
|
|
279
321
|
// 使用内置语音播报功能(v5.6.0+)
|
|
280
322
|
aMapNavi?.setUseInnerVoice(true, true) // 启用内置语音,并回调文字
|
|
281
|
-
|
|
323
|
+
//设置是否为骑步行视图
|
|
324
|
+
aMapNavi?.isNaviTravelView = isNaviTravelView
|
|
282
325
|
// 设置导航视图选项 - 根据 AMapNaviViewOptions API
|
|
283
326
|
val options = AMapNaviViewOptions()
|
|
284
327
|
|
|
285
328
|
// === 基础界面控制 ===
|
|
286
329
|
// 注意:isLayoutVisible 控制整个导航UI布局的显示
|
|
287
330
|
// 设置为 true 将显示导航信息面板(包括距离、时间等)
|
|
288
|
-
options.isLayoutVisible =
|
|
331
|
+
options.isLayoutVisible = showUIElements
|
|
289
332
|
options.isSettingMenuEnabled = true // 显示设置菜单按钮
|
|
290
|
-
options.isCompassEnabled =
|
|
291
|
-
options.isTrafficBarEnabled =
|
|
292
|
-
options.isRouteListButtonShow =
|
|
293
|
-
|
|
333
|
+
options.isCompassEnabled = isCompassEnabled // 显示指南针
|
|
334
|
+
options.isTrafficBarEnabled = androidTrafficBarEnabled // 显示路况条
|
|
335
|
+
options.isRouteListButtonShow = isRouteListButtonShow // 显示路线全览按钮
|
|
336
|
+
|
|
294
337
|
Log.d("ExpoGaodeMapNaviView", "导航UI配置: isLayoutVisible=true, 所有UI元素已启用")
|
|
295
338
|
|
|
296
339
|
// === 地图图层 ===
|
|
297
|
-
options.isTrafficLayerEnabled =
|
|
298
|
-
options.isTrafficLine =
|
|
340
|
+
options.isTrafficLayerEnabled = isTrafficLayerEnabled // 显示交通路况图层
|
|
341
|
+
options.isTrafficLine = isTrafficLine // 显示交通路况线
|
|
299
342
|
|
|
300
343
|
// === 路口放大图和车道信息 ===
|
|
301
|
-
options.isRealCrossDisplayShow =
|
|
344
|
+
options.isRealCrossDisplayShow = isRealCrossDisplayShow // 显示实景路口放大图
|
|
302
345
|
options.setModeCrossDisplayShow(true) // 显示路口3D模型(使用方法而非属性)
|
|
303
346
|
options.isLaneInfoShow = true // 显示车道信息
|
|
304
347
|
options.isEyrieCrossDisplay = true // 显示鹰眼路口图
|
|
@@ -310,32 +353,36 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
310
353
|
|
|
311
354
|
// === 路线和导航箭头 ===
|
|
312
355
|
options.isAutoDrawRoute = true // 自动绘制路线
|
|
313
|
-
options.isNaviArrowVisible =
|
|
356
|
+
options.isNaviArrowVisible = isNaviArrowVisible // 显示导航箭头
|
|
314
357
|
options.isSecondActionVisible = true // 显示辅助操作(如下个路口提示)
|
|
315
358
|
options.isDrawBackUpOverlay = true // 绘制备用路线覆盖物
|
|
359
|
+
if(isVectorLineShow)
|
|
360
|
+
options.isLeaderLineEnabled
|
|
316
361
|
|
|
317
362
|
// === 地图锁车和视角控制 ===
|
|
318
|
-
options.isAutoLockCar =
|
|
363
|
+
options.isAutoLockCar = autoLockCar // 自动锁车
|
|
319
364
|
options.lockMapDelayed = 5000L // 5秒后自动锁车(毫秒)
|
|
320
|
-
options.
|
|
321
|
-
options.isAutoChangeZoom =
|
|
322
|
-
options.
|
|
323
|
-
options.
|
|
365
|
+
options.isAutoDisplayOverview = false // 不自动显示全览
|
|
366
|
+
options.isAutoChangeZoom = autoChangeZoom // 根据导航自动调整缩放级别
|
|
367
|
+
options.zoom = 18 // 锁车时的缩放级别 (14-18)
|
|
368
|
+
options.tilt = 35 // 锁车时的倾斜角度 (0-60)
|
|
324
369
|
|
|
325
370
|
// === 已走路线处理 ===
|
|
326
|
-
options.
|
|
371
|
+
options.isAfterRouteAutoGray = isAfterRouteAutoGray // 走过的路线自动变灰
|
|
327
372
|
|
|
328
373
|
// === 传感器和定位 ===
|
|
329
|
-
options.
|
|
374
|
+
options.isSensorEnable = true // 使用设备传感器
|
|
330
375
|
|
|
331
376
|
// === 夜间模式(已废弃但保留兼容) ===
|
|
332
377
|
// 建议使用 setMapStyle 方法设置地图样式
|
|
333
|
-
options.
|
|
378
|
+
options.isAutoNaviViewNightMode = false // 不自动切换夜间模式
|
|
334
379
|
|
|
335
380
|
// === 鹰眼地图 ===
|
|
336
|
-
options.
|
|
381
|
+
options.isEagleMapVisible = false // 不显示鹰眼地图(小地图)
|
|
337
382
|
|
|
338
383
|
naviView.viewOptions = options
|
|
384
|
+
|
|
385
|
+
naviView.post { updateTopInsetPadding() }
|
|
339
386
|
|
|
340
387
|
// 设置导航视图监听器
|
|
341
388
|
naviView.setAMapNaviViewListener(object : AMapNaviViewListener {
|
|
@@ -364,6 +411,323 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
364
411
|
}
|
|
365
412
|
}
|
|
366
413
|
|
|
414
|
+
private fun getStatusBarHeightPx(): Int {
|
|
415
|
+
return try {
|
|
416
|
+
val resourceId = context.resources.getIdentifier("status_bar_height", "dimen", "android")
|
|
417
|
+
if (resourceId > 0) context.resources.getDimensionPixelSize(resourceId) else 0
|
|
418
|
+
} catch (_: Exception) {
|
|
419
|
+
0
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private fun dpToPx(dp: Double): Int {
|
|
424
|
+
val density = context.resources.displayMetrics.density
|
|
425
|
+
return (dp * density + 0.5).toInt()
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
private fun updateTopInsetPadding() {
|
|
429
|
+
val shouldApplyPadding = androidStatusBarPaddingTopDp != null
|
|
430
|
+
val paddingTopPx = if (shouldApplyPadding) {
|
|
431
|
+
androidStatusBarPaddingTopDp?.let { dpToPx(it) } ?: getStatusBarHeightPx()
|
|
432
|
+
} else {
|
|
433
|
+
//默认返回状态栏高度
|
|
434
|
+
getStatusBarHeightPx()
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (lastAppliedTopPaddingPx == paddingTopPx) {
|
|
438
|
+
return
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
lastAppliedTopPaddingPx = paddingTopPx
|
|
442
|
+
|
|
443
|
+
topInsetPx = paddingTopPx
|
|
444
|
+
|
|
445
|
+
naviView.setPadding(0, 0, 0, 0)
|
|
446
|
+
|
|
447
|
+
applyTopInsetToOverlays(paddingTopPx)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
private fun ensureOverlayInsetHook() {
|
|
451
|
+
if (overlayHooked) {
|
|
452
|
+
return
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
overlayHooked = true
|
|
456
|
+
naviView.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
|
457
|
+
applyTopInsetToOverlays(topInsetPx)
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
private fun applyTopInsetToOverlays(paddingTopPx: Int) {
|
|
462
|
+
if (paddingTopPx <= 0) {
|
|
463
|
+
if (overlayStates.isNotEmpty()) {
|
|
464
|
+
val iterator = overlayStates.entries.iterator()
|
|
465
|
+
while (iterator.hasNext()) {
|
|
466
|
+
val entry = iterator.next()
|
|
467
|
+
val view = entry.key
|
|
468
|
+
val state = entry.value
|
|
469
|
+
view.translationY = state.translationY
|
|
470
|
+
view.setPadding(view.paddingLeft, state.paddingTop, view.paddingRight, view.paddingBottom)
|
|
471
|
+
iterator.remove()
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
val rawTargets = findTopOverlayTargets(naviView)
|
|
478
|
+
val targets = filterTopLevelTargets(naviView, rawTargets)
|
|
479
|
+
if (targets.isEmpty()) {
|
|
480
|
+
val applied = applyTopPaddingToNaviUiLayer(paddingTopPx)
|
|
481
|
+
if (!applied) {
|
|
482
|
+
naviView.post { applyTopPaddingToNaviUiLayer(paddingTopPx) }
|
|
483
|
+
}
|
|
484
|
+
return
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
val targetSet = targets.toHashSet()
|
|
488
|
+
|
|
489
|
+
val iterator = overlayStates.entries.iterator()
|
|
490
|
+
while (iterator.hasNext()) {
|
|
491
|
+
val entry = iterator.next()
|
|
492
|
+
val view = entry.key
|
|
493
|
+
if (!targetSet.contains(view)) {
|
|
494
|
+
val state = entry.value
|
|
495
|
+
view.translationY = state.translationY
|
|
496
|
+
view.setPadding(view.paddingLeft, state.paddingTop, view.paddingRight, view.paddingBottom)
|
|
497
|
+
iterator.remove()
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
for (target in targets) {
|
|
502
|
+
if (!overlayStates.containsKey(target)) {
|
|
503
|
+
overlayStates[target] = OverlayState(
|
|
504
|
+
translationY = target.translationY,
|
|
505
|
+
paddingTop = target.paddingTop
|
|
506
|
+
)
|
|
507
|
+
}
|
|
508
|
+
ensureNoClipChain(target)
|
|
509
|
+
target.translationY = paddingTopPx.toFloat()
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
private fun ensureNoClipChain(view: View) {
|
|
514
|
+
var currentParent = view.parent
|
|
515
|
+
while (currentParent is ViewGroup) {
|
|
516
|
+
currentParent.clipChildren = false
|
|
517
|
+
currentParent.clipToPadding = false
|
|
518
|
+
if (currentParent === naviView) {
|
|
519
|
+
break
|
|
520
|
+
}
|
|
521
|
+
currentParent = currentParent.parent
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
private fun filterTopLevelTargets(root: ViewGroup, targets: List<View>): List<View> {
|
|
526
|
+
if (targets.size <= 1) {
|
|
527
|
+
return targets
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
val set = targets.toHashSet()
|
|
531
|
+
val result = ArrayList<View>(targets.size)
|
|
532
|
+
for (view in targets) {
|
|
533
|
+
var parent = view.parent
|
|
534
|
+
var hasAncestorInTargets = false
|
|
535
|
+
while (parent is View) {
|
|
536
|
+
if (parent === root) {
|
|
537
|
+
break
|
|
538
|
+
}
|
|
539
|
+
if (set.contains(parent)) {
|
|
540
|
+
hasAncestorInTargets = true
|
|
541
|
+
break
|
|
542
|
+
}
|
|
543
|
+
parent = parent.parent
|
|
544
|
+
}
|
|
545
|
+
if (!hasAncestorInTargets) {
|
|
546
|
+
result.add(view)
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return result
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private fun findTopOverlayTargets(root: ViewGroup): List<View> {
|
|
554
|
+
val result = ArrayList<View>()
|
|
555
|
+
val parentHeight = root.height
|
|
556
|
+
val parentWidth = root.width
|
|
557
|
+
if (parentHeight <= 0 || parentWidth <= 0) {
|
|
558
|
+
return result
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
val queue = ArrayDeque<View>()
|
|
562
|
+
for (i in 0 until root.childCount) {
|
|
563
|
+
queue.add(root.getChildAt(i))
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
while (queue.isNotEmpty()) {
|
|
567
|
+
val view = queue.removeFirst()
|
|
568
|
+
val group = view as? ViewGroup
|
|
569
|
+
if (group != null) {
|
|
570
|
+
for (i in 0 until group.childCount) {
|
|
571
|
+
queue.add(group.getChildAt(i))
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
if (!view.isShown) {
|
|
576
|
+
continue
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
val name = view.javaClass.name
|
|
580
|
+
if (name.contains("MapView", ignoreCase = true) ||
|
|
581
|
+
name.contains("Texture", ignoreCase = true) ||
|
|
582
|
+
name.contains("Surface", ignoreCase = true) ||
|
|
583
|
+
name.contains("GLSurface", ignoreCase = true)
|
|
584
|
+
) {
|
|
585
|
+
continue
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
if (view.height <= 0 || view.width <= 0) {
|
|
589
|
+
continue
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (view.top > 1) {
|
|
593
|
+
continue
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
if (view.height >= (parentHeight * 0.6f).toInt()) {
|
|
597
|
+
continue
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
val wideEnough = view.width >= (parentWidth * 0.5f).toInt()
|
|
601
|
+
val likelyUi = wideEnough && (view.isClickable || (view as? ViewGroup)?.childCount ?: 0 > 0)
|
|
602
|
+
if (!likelyUi) {
|
|
603
|
+
continue
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
result.add(view)
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return result
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
private fun applyTopPaddingToNaviUiLayer(paddingTopPx: Int): Boolean {
|
|
613
|
+
val uiRoot = findNaviUiRoot(naviView) ?: return false
|
|
614
|
+
|
|
615
|
+
uiRoot.setPadding(uiRoot.paddingLeft, paddingTopPx, uiRoot.paddingRight, uiRoot.paddingBottom)
|
|
616
|
+
uiRoot.clipToPadding = false
|
|
617
|
+
return true
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
private fun findNaviUiRoot(root: ViewGroup): ViewGroup? {
|
|
621
|
+
var best: ViewGroup? = null
|
|
622
|
+
var bestScore = Int.MIN_VALUE
|
|
623
|
+
|
|
624
|
+
val queue = ArrayDeque<View>()
|
|
625
|
+
for (i in 0 until root.childCount) {
|
|
626
|
+
queue.add(root.getChildAt(i))
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
while (queue.isNotEmpty()) {
|
|
630
|
+
val view = queue.removeFirst()
|
|
631
|
+
val group = view as? ViewGroup
|
|
632
|
+
if (group != null) {
|
|
633
|
+
val score = scoreAsUiRootCandidate(group)
|
|
634
|
+
if (score > bestScore) {
|
|
635
|
+
bestScore = score
|
|
636
|
+
best = group
|
|
637
|
+
}
|
|
638
|
+
for (i in 0 until group.childCount) {
|
|
639
|
+
queue.add(group.getChildAt(i))
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return if (bestScore > 0) best else null
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
private fun scoreAsUiRootCandidate(group: ViewGroup): Int {
|
|
648
|
+
val name = group.javaClass.name
|
|
649
|
+
if (name.contains("MapView", ignoreCase = true) ||
|
|
650
|
+
name.contains("Texture", ignoreCase = true) ||
|
|
651
|
+
name.contains("Surface", ignoreCase = true) ||
|
|
652
|
+
name.contains("GLSurface", ignoreCase = true)
|
|
653
|
+
) {
|
|
654
|
+
return Int.MIN_VALUE
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
var score = 0
|
|
658
|
+
|
|
659
|
+
val lp = group.layoutParams
|
|
660
|
+
if (lp != null) {
|
|
661
|
+
if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT && lp.height == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
662
|
+
score += 4
|
|
663
|
+
} else if (lp.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
|
664
|
+
score += 2
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
if (group.childCount >= 3) {
|
|
669
|
+
score += 2
|
|
670
|
+
} else if (group.childCount >= 1) {
|
|
671
|
+
score += 1
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
if (name.contains("RelativeLayout", ignoreCase = true) || name.contains("FrameLayout", ignoreCase = true)) {
|
|
675
|
+
score += 1
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
return score
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
fun applyAndroidStatusBarPaddingTop(topDp: Double?) {
|
|
684
|
+
androidStatusBarPaddingTopDp = topDp
|
|
685
|
+
updateTopInsetPadding()
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
fun applyShowUIElements(visible: Boolean) {
|
|
689
|
+
showUIElements = visible
|
|
690
|
+
val options = naviView.viewOptions
|
|
691
|
+
options.isLayoutVisible = visible
|
|
692
|
+
naviView.viewOptions = options
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
fun applyAndroidTrafficBarEnabled(enabled: Boolean) {
|
|
696
|
+
androidTrafficBarEnabled = enabled
|
|
697
|
+
val options = naviView.viewOptions
|
|
698
|
+
options.isTrafficBarEnabled = enabled
|
|
699
|
+
naviView.viewOptions = options
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
fun applyShowTrafficButton(enabled: Boolean) {
|
|
703
|
+
isTrafficLayerEnabled = enabled
|
|
704
|
+
val options = naviView.viewOptions
|
|
705
|
+
options.isTrafficLayerEnabled = enabled
|
|
706
|
+
naviView.viewOptions = options
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
fun applyShowBrowseRouteButton(enabled: Boolean) {
|
|
710
|
+
isRouteListButtonShow = enabled
|
|
711
|
+
val options = naviView.viewOptions
|
|
712
|
+
options.isRouteListButtonShow = enabled
|
|
713
|
+
naviView.viewOptions = options
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
fun applyShowGreyAfterPass(enabled: Boolean){
|
|
717
|
+
isAfterRouteAutoGray = enabled
|
|
718
|
+
val options = naviView.viewOptions
|
|
719
|
+
options.isAfterRouteAutoGray = enabled
|
|
720
|
+
naviView.viewOptions = options
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
fun applyShowVectorline(enabled: Boolean){
|
|
724
|
+
isVectorLineShow = enabled
|
|
725
|
+
val options = naviView.viewOptions
|
|
726
|
+
if(enabled)
|
|
727
|
+
options.isLeaderLineEnabled
|
|
728
|
+
naviView.viewOptions = options
|
|
729
|
+
}
|
|
730
|
+
|
|
367
731
|
fun startNavigation(startLat: Double, startLng: Double, endLat: Double, endLng: Double, promise: expo.modules.kotlin.Promise) {
|
|
368
732
|
Log.d("ExpoGaodeMapNaviView", "startNavigation: $startLat, $startLng, $endLat, $endLng, naviType: $naviType")
|
|
369
733
|
try {
|
|
@@ -454,29 +818,41 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
454
818
|
}
|
|
455
819
|
|
|
456
820
|
fun applyAutoLockCar(enabled: Boolean) {
|
|
821
|
+
autoLockCar = enabled
|
|
457
822
|
val options = naviView.viewOptions
|
|
458
823
|
options.isAutoLockCar = enabled
|
|
459
824
|
naviView.viewOptions = options
|
|
460
825
|
}
|
|
461
826
|
|
|
462
827
|
fun applyAutoChangeZoom(enabled: Boolean) {
|
|
828
|
+
autoChangeZoom = enabled
|
|
463
829
|
val options = naviView.viewOptions
|
|
464
830
|
options.isAutoChangeZoom = enabled
|
|
465
831
|
naviView.viewOptions = options
|
|
466
832
|
}
|
|
467
833
|
|
|
468
834
|
fun applyTrafficLayerEnabled(enabled: Boolean) {
|
|
835
|
+
isTrafficLine = enabled
|
|
469
836
|
val options = naviView.viewOptions
|
|
470
|
-
options.
|
|
837
|
+
options.isTrafficLine = enabled
|
|
471
838
|
naviView.viewOptions = options
|
|
472
839
|
}
|
|
473
840
|
|
|
474
841
|
fun applyRealCrossDisplay(enabled: Boolean) {
|
|
842
|
+
isRealCrossDisplayShow = enabled
|
|
475
843
|
val options = naviView.viewOptions
|
|
476
844
|
options.isRealCrossDisplayShow = enabled
|
|
477
845
|
naviView.viewOptions = options
|
|
478
846
|
}
|
|
479
|
-
|
|
847
|
+
|
|
848
|
+
fun applyShowCompassEnabled(enabled: Boolean){
|
|
849
|
+
isCompassEnabled = enabled
|
|
850
|
+
val options = naviView.viewOptions
|
|
851
|
+
options.isCompassEnabled = enabled
|
|
852
|
+
naviView.viewOptions = options
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
|
|
480
856
|
fun applyNaviMode(mode: Int) {
|
|
481
857
|
// 0: 车头朝上 1: 正北朝上
|
|
482
858
|
naviView.naviMode = mode
|
|
@@ -491,6 +867,11 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
491
867
|
// 夜间模式设置 - isNightMode 属性可能不存在
|
|
492
868
|
try {
|
|
493
869
|
val options = naviView.viewOptions
|
|
870
|
+
if(enabled){
|
|
871
|
+
options.setMapStyle(MapStyle.NIGHT, null)
|
|
872
|
+
}else{
|
|
873
|
+
options.setMapStyle(MapStyle.DAY, null)
|
|
874
|
+
}
|
|
494
875
|
// options.isNightMode = enabled // 该属性可能不存在
|
|
495
876
|
// 可以通过其他方式设置夜间模式
|
|
496
877
|
naviView.viewOptions = options
|
|
@@ -512,7 +893,8 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
512
893
|
Log.e("ExpoGaodeMapNaviView", "Failed to set car overlay visibility", e)
|
|
513
894
|
}
|
|
514
895
|
}
|
|
515
|
-
|
|
896
|
+
|
|
897
|
+
|
|
516
898
|
/**
|
|
517
899
|
* 设置是否显示交通信号灯
|
|
518
900
|
* @param visible true-显示 false-隐藏
|
|
@@ -578,7 +960,12 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
578
960
|
Log.e("ExpoGaodeMapNaviView", "Failed to set traffic light view visibility", e)
|
|
579
961
|
}
|
|
580
962
|
}
|
|
581
|
-
|
|
963
|
+
|
|
964
|
+
fun applyIsNaviTravelView(enabled: Boolean){
|
|
965
|
+
isNaviTravelView = enabled
|
|
966
|
+
aMapNavi?.isNaviTravelView = enabled
|
|
967
|
+
}
|
|
968
|
+
|
|
582
969
|
/**
|
|
583
970
|
* 设置路线转向箭头的可见性
|
|
584
971
|
* @param visible true-显示 false-隐藏
|
|
@@ -586,8 +973,9 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
586
973
|
*/
|
|
587
974
|
fun applyNaviArrowVisible(visible: Boolean) {
|
|
588
975
|
try {
|
|
976
|
+
isNaviArrowVisible = visible
|
|
589
977
|
val options = naviView.viewOptions
|
|
590
|
-
options.
|
|
978
|
+
options.isNaviArrowVisible = visible
|
|
591
979
|
naviView.viewOptions = options
|
|
592
980
|
Log.d("ExpoGaodeMapNaviView", "Navi arrow visibility set to: $visible")
|
|
593
981
|
} catch (e: Exception) {
|
|
@@ -649,4 +1037,4 @@ class ExpoGaodeMapNaviView(context: Context, appContext: AppContext) : ExpoView(
|
|
|
649
1037
|
Log.e("ExpoGaodeMapNaviView", "Error destroying navi view", e)
|
|
650
1038
|
}
|
|
651
1039
|
}
|
|
652
|
-
}
|
|
1040
|
+
}
|
package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNaviViewModule.kt
CHANGED
|
@@ -72,9 +72,13 @@ class ExpoGaodeMapNaviViewModule : Module() {
|
|
|
72
72
|
view.applyCarOverlayVisible(visible)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
Prop<Boolean>("
|
|
75
|
+
Prop<Boolean>("showTrafficLights") { view, visible ->
|
|
76
76
|
view.applyTrafficLightsVisible(visible)
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
Prop<Boolean>("showCompassEnabled") {view, enabled ->
|
|
80
|
+
view.applyShowCompassEnabled(enabled)
|
|
81
|
+
}
|
|
78
82
|
|
|
79
83
|
Prop<Map<String, Boolean>?>("routeMarkerVisible") { view, config ->
|
|
80
84
|
config?.let {
|
|
@@ -101,7 +105,44 @@ class ExpoGaodeMapNaviViewModule : Module() {
|
|
|
101
105
|
Prop<Boolean>("showTrafficLightView") { view, show ->
|
|
102
106
|
view.applyShowTrafficLightView(show)
|
|
103
107
|
}
|
|
104
|
-
|
|
108
|
+
|
|
109
|
+
//设置是否为骑步行视图
|
|
110
|
+
Prop<Boolean>("isNaviTravelView") { view, isRideStepView ->
|
|
111
|
+
view.applyIsNaviTravelView(isRideStepView)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
Prop<Double?>("androidStatusBarPaddingTop") { view, topDp ->
|
|
115
|
+
view.applyAndroidStatusBarPaddingTop(topDp)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
Prop<Boolean>("showCamera") { view, enabled ->
|
|
119
|
+
view.applyShowCamera(enabled)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
Prop<Boolean>("showUIElements") { view, visible ->
|
|
123
|
+
view.applyShowUIElements(visible)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Prop<Boolean>("showTrafficBar") { view, enabled ->
|
|
127
|
+
view.applyAndroidTrafficBarEnabled(enabled)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
Prop<Boolean>("showTrafficButton"){ view, enabled ->
|
|
131
|
+
view.applyShowTrafficButton(enabled)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
Prop<Boolean>("showBrowseRouteButton") { view, enabled ->
|
|
135
|
+
view.applyShowBrowseRouteButton(enabled)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
Prop<Boolean>("showVectorline"){ view, enabled ->
|
|
139
|
+
view.applyShowVectorline(enabled)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
Prop<Boolean>("showGreyAfterPass") { view, enabled ->
|
|
143
|
+
view.applyShowGreyAfterPass(enabled)
|
|
144
|
+
}
|
|
145
|
+
|
|
105
146
|
// 方法
|
|
106
147
|
AsyncFunction("startNavigation") { view: ExpoGaodeMapNaviView, startLat: Double, startLng: Double, endLat: Double, endLng: Double, promise: expo.modules.kotlin.Promise ->
|
|
107
148
|
view.startNavigation(startLat, startLng, endLat, endLng, promise)
|
|
@@ -112,4 +153,4 @@ class ExpoGaodeMapNaviViewModule : Module() {
|
|
|
112
153
|
}
|
|
113
154
|
}
|
|
114
155
|
}
|
|
115
|
-
}
|
|
156
|
+
}
|
package/android/src/main/java/expo/modules/gaodemap/navigation/ExpoGaodeMapNavigationModule.kt
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
package expo.modules.gaodemap.navigation
|
|
2
2
|
|
|
3
|
+
import android.annotation.SuppressLint
|
|
3
4
|
import android.content.Context
|
|
4
5
|
import com.amap.api.navi.AMapNavi
|
|
5
6
|
import com.amap.api.navi.model.AMapCarInfo
|
|
@@ -43,6 +44,7 @@ class ExpoGaodeMapNavigationModule : Module() {
|
|
|
43
44
|
private val independentRouteManager = IndependentRouteManager()
|
|
44
45
|
private var independentRouteService: IndependentRouteService? = null
|
|
45
46
|
|
|
47
|
+
@SuppressLint("SuspiciousIndentation")
|
|
46
48
|
override fun definition() = ModuleDefinition {
|
|
47
49
|
Name("ExpoGaodeMapNavigation")
|
|
48
50
|
|
|
@@ -75,12 +75,11 @@ exports.NaviView = React.forwardRef((props, ref) => {
|
|
|
75
75
|
// 创建 API 引用
|
|
76
76
|
const apiRef = React.useMemo(() => ({
|
|
77
77
|
startNavigation: async (start, end, type) => {
|
|
78
|
-
var _a, _b;
|
|
79
78
|
if (!nativeRef.current)
|
|
80
79
|
throw new Error('NaviView not initialized');
|
|
81
80
|
// 将对象解构为单独的参数传递给原生层
|
|
82
|
-
const startLat =
|
|
83
|
-
const startLng =
|
|
81
|
+
const startLat = start?.latitude ?? 0;
|
|
82
|
+
const startLng = start?.longitude ?? 0;
|
|
84
83
|
const endLat = end.latitude;
|
|
85
84
|
const endLng = end.longitude;
|
|
86
85
|
return nativeRef.current.startNavigation(startLat, startLng, endLat, endLng);
|