如何自动调整缩放以适应 Google Maps Compose 中的所有标记?

问题描述 投票:0回答:1

Google Maps Compose 库提供

cameraPositionState 
使用以下代码来容纳 1 个具有缩放功能的位置

val singapore = LatLng(1.35, 103.87)
val cameraPositionState = rememberCameraPositionState {
position = CameraPosition.fromLatLngZoom(singapore, 10f)
}
GoogleMap(
modifier = Modifier.fillMaxSize(),
cameraPositionState = cameraPositionState)

如何在多个地点完成相同的任务?我有一个位置列表,我想初始化

GoogleMap
以显示所有位置标记。

kotlin google-maps android-jetpack-compose google-maps-compose
1个回答
0
投票

使用
LatLngBounds.builder()
根据一组
LatLng
点创建最小边界

您可以使用

LatLngs
作为此处记录的
LatLngBounds
的参数,而不是使用
CameraUpdateFactory.NewLatLngBounds()
来指定相机位置:https://developers.google.com/android/reference/com/google/android /gms/maps/CameraUpdateFactory#public-static-cameraupdate-newlatlngbounds-latlngbounds-bounds,-int-padding

但是您需要首先获得

LatLngBounds
值。在这种情况下,您可以使用
LatLngBounds.builder()
方法创建要在相机更新中使用的
bounds
实例。

所以假设我有以下坐标用于实例化标记:

private val santiago = LatLng(-33.4489, -70.6693)
private val bogota = LatLng(-4.7110, -74.0721)
private val lima = LatLng(-12.0464, -77.0428)
private val salvador = LatLng(-12.9777, -38.5016)

一旦我有了它,我就需要实例化构建器:

val boundsBuilder = LatLngBounds.builder()

创建坐标列表:

val coordinates = listOf(
            santiago,
            bogota,
            lima,
            salvador
        )

然后循环遍历它并使用

include()
builder()
方法遍历每个 LatLng 坐标:

for (coordinate in coordinates) {
    boundsBuilder.include(coordinate)
}

然后使用

build()
方法构建它,并将其返回值存储为
bounds
,以便稍后在更新相机时使用。

val bounds = boundsBuilder.build()

然后在您的

setContent
中,如果想要在初始加载时更新相机以包含所有标记,您可以在
cameraPositionState.move()
可组合项中使用
LaunchedEffect
方法。它看起来像这样:

LaunchedEffect(key1 = true ){
    cameraPositionState.move(
        update = CameraUpdateFactory.newLatLngBounds(bounds, 100)
    )
}

请注意,

cameraPositionState.move()
方法有一个
update
参数。在这里,您只需将之前通过将
bounds
值转换为
update
 获得的 
CameraUpdateFactory.newLatLngBounds(BOUNDS_VALUE_HERE, PADDING_VALUE_HERE)

值即可

这是一个示例实现,您可以尝试,我还添加了一个按钮供您在初始加载之外测试相机更新:

private val santiago = LatLng(-33.4489, -70.6693)
private val bogota = LatLng(-4.7110, -74.0721)
private val lima = LatLng(-12.0464, -77.0428)
private val salvador = LatLng(-12.9777, -38.5016)
private val center = LatLng(-18.000, -58.000)
private val defaultCameraPosition1 = CameraPosition.fromLatLngZoom(center, 2f)

class StackOverflowSample : ComponentActivity(), OnMapsSdkInitializedCallback {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        MapsInitializer.initialize(applicationContext, MapsInitializer.Renderer.LATEST, this)
        val boundsBuilder = LatLngBounds.builder()

        val coordinates = listOf(
            santiago,
            bogota,
            lima,
            salvador
        )

        for (coordinate in coordinates) {
            boundsBuilder.include(coordinate)
        }
        val bounds = boundsBuilder.build()
        setContent {
            // Observing and controlling the camera's state can be done with a CameraPositionState
            val cameraPositionState = rememberCameraPositionState {
                position = defaultCameraPosition1
            }
            val mapProperties by remember {
                mutableStateOf(MapProperties(mapType = MapType.NORMAL))
            }
            val marker1State = rememberMarkerState(position = santiago)
            val marker2State = rememberMarkerState(position = bogota)
            val marker3State = rememberMarkerState(position = lima)
            val marker4State = rememberMarkerState(position = salvador)

            // Drawing on the map is accomplished with a child-based API
            val markerClick: (Marker) -> Boolean = {
                Log.d(TAG, "${it.title} was clicked")
                cameraPositionState.projection?.let { projection ->
                    Log.d(TAG, "The current projection is: $projection")
                }
                false
            }
            Column(
                modifier = Modifier.fillMaxSize()
            ) {
                Button(onClick = {
                    cameraPositionState.move(
                        update = CameraUpdateFactory.newLatLngBounds(bounds, 100)
                    )
                }) {
                    Text("Update Camera")
                }
                Box(Modifier.fillMaxSize()) {
                    LaunchedEffect(key1 = true ){
                        cameraPositionState.move(
                            update = CameraUpdateFactory.newLatLngBounds(bounds, 100)
                        )
                    }
                    GoogleMap(
                        modifier = Modifier.matchParentSize(),
                        googleMapOptionsFactory = {
                            GoogleMapOptions().mapId("DEMO_MAP_ID")
                        },
                        cameraPositionState = cameraPositionState,
                        properties = mapProperties,
                        onPOIClick = {
                            Log.d(TAG, "POI clicked: ${it.name}")
                        }
                    ) {

                        val textView = TextView(this@AdvancedMarkersActivity)
                        textView.text = "Hello!!"
                        textView.setBackgroundColor(Color.BLACK)
                        textView.setTextColor(Color.YELLOW)

                        AdvancedMarker(
                            state = marker4State,
                            onClick = markerClick,
                            collisionBehavior = 1,
                            iconView = textView,
                            title="Marker 4"
                        )

                        val pinConfig = PinConfig.builder()
                            .setBackgroundColor(Color.MAGENTA)
                            .setBorderColor(Color.WHITE)
                            .build()

                        AdvancedMarker(
                            state = marker1State,
                            onClick = markerClick,
                            collisionBehavior = 1,
                            pinConfig = pinConfig,
                            title="Marker 1"
                        )

                        val glyphOne = PinConfig.Glyph("A", Color.BLACK)
                        val pinConfig2 = PinConfig.builder()
                            .setGlyph(glyphOne)
                            .build()

                        AdvancedMarker(
                            state = marker2State,
                            onClick = markerClick,
                            collisionBehavior = 1,
                            pinConfig = pinConfig2,
                            title="Marker 2"
                        )

                        val glyphImage: Int = ic_menu_myplaces
                        val descriptor = BitmapDescriptorFactory.fromResource(glyphImage)
                        val pinConfig3 = PinConfig.builder()
                            .setGlyph(PinConfig.Glyph(descriptor))
                            .build()

                        AdvancedMarker(
                            state = marker3State,
                            onClick = markerClick,
                            collisionBehavior = 1,
                            pinConfig = pinConfig3,
                            title="Marker 3"
                        )

                    }
                }
            }

        }
    }

    override fun onMapsSdkInitialized(renderer: MapsInitializer.Renderer) {
        when (renderer) {
            MapsInitializer.Renderer.LATEST -> Log.d("MapsDemo", "The latest version of the renderer is used.")
            MapsInitializer.Renderer.LEGACY -> Log.d("MapsDemo", "The legacy version of the renderer is used.")
            else -> {}
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.