20

In Compose, how do we get the position or size of a Composable in a screen ? For example, I'm trying to focus the map camera between specific bounds and adding padding. Here I need to get the padding corresponding to the pager top position and TopBar bottom position.

enter image description here

Currently the code of this screen is the following:

BoxWithConstraints {
        MapViewWithMarkers(...)
        TopAppBar(
            modifier = Modifier
                .fillMaxWidth()
                .statusBarsPadding(),
            backgroundColor = Color.Transparent,
            elevation = 0.dp,
        )
        HorizontalPager(
            state = pagerState,
            modifier = Modifier
                .align(Alignment.BottomCenter)
                .fillMaxWidth()
                .navigationBarsPadding()
                .padding(bottom = 32.dp),
            itemSpacing = 8.dp,
        ) { page ->
            val hikeOnMapCard = hikeMarkerList[page]
            HikeOnMapCard(hikeOnMapCard) {
                viewModel.hikeOnMapCardClicked(hikeOnMapCard.id)
            }
        }
    }

I would like to forward to the MapViewWithMarkers Composable the padding corresponding to the TopAppBar size and Pager size on this screen

Thanks !

Guimareshh
  • 1,214
  • 2
  • 15
  • 26

1 Answers1

26

To get the position and the size of a composable you can use the onGloballyPositioned modifier.

Something like:

 var sizeTopBar by remember { mutableStateOf(IntSize.Zero) }
 var positionInRootTopBar by remember { mutableStateOf(Offset.Zero) }

 TopAppBar(
        modifier = Modifier
          .onGloballyPositioned { coordinates ->
             // size
             sizeTopBar = coordinates.size

             // global position (local also available)
             positionInRootTopBar = coordinates.positionInRoot() 

          }
       //...
 )

With complex layout to measure and layout multiple composables, use the Layout composable instead. This composable allows you to measure and lay out children manually.

codingjeremy
  • 5,215
  • 1
  • 36
  • 39
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841