Skip to content
DeveloperMemos

Measuring Composable size using BoxWithConstraints

Android, Jetpack, Compose, Kotlin1 min read

I figured out how measure/use the size of a parent Composable in Jetpack Compose using BoxWithConstraints so I thought I'd write about it here. For reference SwiftUI has something called GeometryReader, you can wrap a view inside it and it will provide the size(width, height etc.) of itself inside a closure. I was wondering if there was something similar in Jetpack Compose and it looks like the closest thing is BoxWithConstraints.

My specific use case was that I wanted to figure out how to implement an adaptive banner in Jetpack Compose. You need to know the width of the device screen, or more specifically the width of the view you are going to place the banner inside. I was able to wrap my AndroidView inside a BoxWithConstraints and pass the width to it. My final implementation looked something like this:

1BoxWithConstraints {
2 // Get the maximum width value
3 val width = maxWidth.value.toInt()
4
5 AndroidView(
6 modifier = Modifier.fillMaxWidth(),
7 factory = { context ->
8 AdsManager.createBanner(
9 context = context,
10 width = width
11 )
12 }
13 )
14}

I only used the width in my use case but you can also access the max height dimension with maxHeight. Interestingly enough it also provides minHeight and minWidth as well. Both of these values came to 0dp respectively for me. It also seems to respond to orientation changes seamlessly too, which is great.

Using onGloballyPositioned

There's also another way to measure a specific Composable, using the onGloballyPositioned. I didn't end up going with this approach but I thought it might be useful to add it to this article as well. You don't wrap a Composable - it's just a normal Modifier, used like this:

1@Composable
2fun Example(
3 density: Density = LocalDensity.current
4) {
5 var width by remember {
6 mutableStateOf(0.dp)
7 }
8
9 Column(
10 Modifier
11 .onGloballyPositioned { coordinates ->
12 width = with(density) { coordinates.size.width.toDp() }
13 }) {
14 Text(text = "Some kinda text")
15 }
16}