146

I am wondering how to get the screen width and height with Jetpack Compose?

Is there any way you can retrieve the screen dimensions other than getWindowManager().getDefaultDisplay()?

10 Answers 10

289

You can achieve this with LocalConfiguration.current:

@Composable
fun PostView() {
  val configuration = LocalConfiguration.current

  val screenHeight = configuration.screenHeightDp.dp
  val screenWidth = configuration.screenWidthDp.dp

  ...

}

Sign up to request clarification or add additional context in comments.

7 Comments

For some weird reason, LocalConfiguration is giving me screenWidth of landscape orientation even though I switched from Landscape to Portrait. Is anyone else facing this issue?
If you want to get the size in pixels: val screenDensity = configuration.densityDpi / 160f and multiply with dp, for example val screenHeight = configuration.screenHeightDp.toFloat() * screenDensity. You might want to round to a whole number as well. since px is Int.
Probably a better way to get the size in pixels: val density = LocalDensity.current; val configuration = LocalConfiguration.current; val screenWidthPx = with(density) {configuration.screenWidthDp.dp.roundToPx()}
@hippietrail It's a function in Density.kt.
Note, that "screenHeightDp" doesn't include insets as per documentation: "The height of the available screen space in dp units excluding the area occupied by window insets, such as the status bar, navigation bar, and cutouts."
|
27

To get the screen width and height in pixels, I am using this approach. This works well for me and you can also use this for making responsive UI in Jetpack Compose.

@Composable
fun ScreenSizeHelper() {        
    val context = LocalContext.current    
    val displayMetrics = context.resources.displayMetrics
    
    // Width and height of screen
    val width = displayMetrics.widthPixels
    val height = displayMetrics.heightPixels

    // Device density
    val density = displayMetrics.density       
}

1 Comment

Unlike the other answer this DOES include any window inset area, which might be what you want...
11

I don't think it's the best way to do it but you can try this:

class Size {
    @Composable
    fun height(): Int {
        val configuration = LocalConfiguration.current
        return configuration.screenHeightDp
    }
    @Composable
    fun width(): Int {
        val configuration = LocalConfiguration.current
        return configuration.screenWidthDp
    }
}

and then use this values like that :

val size = Size()
val screenHeight = size.height()

Box(modifier = Modifier.height((screenHeigh/2).dp)) {
    //content
}

Comments

9

Other workarounds include:-

A.) Declaring a BoxWithConstraints at the highest level of the hierarchy, then accessing the maxHeight and equivalent width attributes exposed inside the scope of the box

B.) Using custom layouts

Layout(
 content = { ... }
){ measurables, constraints ->
 //Exposes constraints.maxWidth, and a height equivalent
}

Comments

7

As stated here on this Android Docs:

"Because the composable is not a screen-level composable, we also should not use the current window metrics directly, in order to maximize reusability."

With BoxWithConstraints you will get the actual available size, not the full screen size.

It facilitates in some situation where you have paddings, for instance:

@Composable
fun Card(/* ... */) {
    BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                //...
            }
        } else {
            Row{
              //...
            }
        }
    }
}

It gives you a maxWidth and a maxHeight to create your logic. More info here on this Android Docs.

Hope it helps!

Comments

3

Add the dependency with Bom:

implementation(platform("androidx.compose:compose-bom:2025.05.00"))
...
implementation("androidx.compose.material3.adaptive:adaptive")

Without Bom:

implementation("androidx.compose.material3.adaptive:adaptive:1.2.0-alpha05")

Use it like this:

@OptIn(ExperimentalMaterial3AdaptiveApi::class)
@Composable
fun PostView() {

  val screenHeight = currentWindowDpSize().height // already in Dp
  val screenWidth = currentWindowDpSize().width // already in Dp

  ...

}

I advise you watch this video from the Android team.

Comments

2

Using LocalConfiguration.current is not recommended. LocalWindowInfo.current.containerSize is the way to go since compose-ui 1.8.0-beta02 (release note)

As per the lint check warning:

Configuration.screenWidthDp and Configuration.screenHeightDp have different insets behaviour depending on target SDK version, and are rounded to the nearest Dp. This means that using these values in composition to size a layout can result in issues, as these values do not accurately represent the actual available window size. Instead it is recommended to use WindowInfo.containerSize which accurately represents the window size.

4 Comments

also need to tell it that 'configuration.screenHeightDP.dp (or configuration.screenWidthDP.dp) ' is changed to configuration.height.dp (or configuration.width.dp)
@YoungLee I think you mean containerSize.height and containerSize.width which must be called like this to get values in dp: with(LocalDensity.current) { LocalWindowInfo.current.containerSize.height.toDp() }
Your words are correct in manual, but in performance, there is a difference between 'current.containerSize.height' and 'screenHeightDp'. For example, when adjusting the height of a modal in a view, 'current.containerSize.height' does not reflect the request of adjusting. In addition, the 'toDp()' function does not match (unstable) with material3.
I think this is a very misleading lint. Android Studio tends to show a warning for every usage of them; however, just replacing a config height with window height is going to ruin everything because the value from LocalWindowInfo has no regard for density. So you should use toDp() method; however, that method is only usable using with(LocalDensity.current) {}.
2

If you want use this sizes in you composables you should use density alongside containerSize

val containerSize = LocalWindowInfo.current.containerSize
val density = LocalDensity.current.density

val screenHeight = containerSize.height.dp / density
val screenWidth = containerSize.width.dp / density

Comments

0

You shouldn't actually use getWindowManager().getDefaultDisplay() anymore. It's deprecated. You can use LocalConfiguration.current instead. Here's a sample function:

@Composable
fun ScreenDimensions() {
    val configuration = LocalConfiguration.current
    val screenWidth = configuration.screenWidthDp.dp
    val screenHeight = configuration.screenHeightDp.dp

    Text("Width: $screenWidth, Height: $screenHeight")
}

Comments

-2

This code works for me

@Composable
fun displayMe(){
  val isTablet = ((LocalConfiguration.current.screenLayout
                 and Configuration.SCREENLAYOUT_SIZE_MASK)
                 >= Configuration.SCREENLAYOUT_SIZE_LARGE)
...
}

1 Comment

This is not related

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.