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
以显示所有位置标记。
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 -> {}
}
}
}