Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Column with .scrollable() modifier breaks map vertical scroll

The problem

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.

Code

LocationInput (child)

// 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 ->

    }
  }
}

ScrollableColumn (parent)

@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)
  }
}

Screen Capture

enter image description here

like image 227
Maksymilian Tomczyk Avatar asked Sep 18 '25 10:09

Maksymilian Tomczyk


1 Answers

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.

Code

// 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 ->

    }
like image 197
Maksymilian Tomczyk Avatar answered Sep 21 '25 02:09

Maksymilian Tomczyk