Reputation: 1341
I'm trying to implement simple map view inside scrollable column. The problem is that I can't scroll map vertically, as scroll event is captured by column and instead of map, whole column is scrolling. Is there any way to disable column scrolling on map element? I thought about using .nestedScroll()
modifier, but I can't find a way to make it work as desired.
// Not important in context of question, but I left it so the code is complete
@Composable
private fun rememberMapLifecycleObserver(mapView: MapView): LifecycleEventObserver =
remember(mapView) {
LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_CREATE -> mapView.onCreate(Bundle())
Lifecycle.Event.ON_START -> mapView.onStart()
Lifecycle.Event.ON_RESUME -> mapView.onResume()
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
Lifecycle.Event.ON_STOP -> mapView.onStop()
Lifecycle.Event.ON_DESTROY -> mapView.onDestroy()
else -> throw IllegalStateException()
}
}
}
// Not important in context of question, but I left it so the code is complete
@Composable
private fun rememberMapViewWithLifecycle(): MapView {
val context = LocalContext.current
val mapView = remember {
MapView(context)
}
// Makes MapView follow the lifecycle of this composable
val lifecycleObserver = rememberMapLifecycleObserver(mapView)
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle) {
lifecycle.addObserver(lifecycleObserver)
onDispose {
lifecycle.removeObserver(lifecycleObserver)
}
}
return mapView
}
@Composable
fun LocationInput() {
val map = rememberMapViewWithLifecycle()
Column(Modifier.fillMaxSize()) {
var mapInitialized by remember(map) { mutableStateOf(false) }
val googleMap = remember { mutableStateOf<GoogleMap?>(null) }
LaunchedEffect(map, mapInitialized) {
if (!mapInitialized) {
googleMap.value = map.awaitMap()
googleMap.value!!.uiSettings.isZoomGesturesEnabled = true
mapInitialized = true
}
}
AndroidView({ map }, Modifier.clip(RoundedCornerShape(6.dp))) { mapView ->
}
}
}
@Composable
fun TallView() {
Column(Modifier.verticalScroll(rememberScrollState())) {
Spacer(Modifier.height(15.dp))
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Row(Modifier.height(250.dp)) {
LocationInput()
}
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
Text(text = "Content", style = MaterialTheme.typography.h3)
}
}
Upvotes: 4
Views: 2793
Reputation: 1341
Okay, so after I posted a question I tried to fix a problem again, and I found a working solution. However I'm not sure if it's the best way to achieve desired effect.
I'm manually handling drag event on AndroidView used to present map.
// AndroidView in LocationInput file:
AndroidView({ map },
Modifier
.clip(RoundedCornerShape(6.dp))
.pointerInput(Unit) {
detectDragGestures { change, dragAmount ->
change.consumeAllChanges()
googleMap.value!!.moveCamera(
CameraUpdateFactory.scrollBy(
dragAmount.x * -1,
dragAmount.y * -1
)
)
}
})
{ mapView ->
}
Upvotes: 2