8

How Android @Compose will handle screen size and orientation in Android. I am not able to find suitable answer after googling. Can someone Answer this question.

1

4 Answers 4

4

You can check for orientation like this:

val configuration = LocalConfiguration.current
when(configuration.orientation) {
    Configuration.ORIENTATION_LANDSCAPE -> {}
    Configuration.ORIENTATION_PORTRAIT -> {}
    Configuration.ORIENTATION_SQUARE -> {}
    Configuration.ORIENTATION_UNDEFINED -> {}
}

For screen size:

BoxWithConstraints() {
    // thats what you can access:
    this.maxWidth
    this.maxHeight
    this.minWidth
    this.minHeight
}
0
4

With 1.0.x you can use the BoxWithConstraints composable to define different ui based on the screen size.

Something like:

BoxWithConstraints {
        if (minWidth < 480.dp) {
            /* .... */
        } else if (minWidth < 720.dp) {
            /* .... */
        } else {
            /* .... */
        }
    }

To handle the orientation you can use LocalConfiguration.
Something like:

val configuration = LocalConfiguration.current
when (configuration.orientation) {
    Configuration.ORIENTATION_LANDSCAPE -> {
        /* ... */
    }
    else -> {
        /* ... */
    }
}

}

2
  • 1
    Thanks. But what if we want to change the modifier based on screen size? For example, we want to limit the column width to certain max allowed value on large screens. Commented Oct 26, 2021 at 7:13
  • @Ehsan Shadi Make when retuen different modifiers and use then to append if required Commented Jan 11, 2022 at 19:05
1

Adding an updated answer based on the new androidx.compose.material3.windowsizeclass library.

You can now use WindowSizeClass to query the width and height classes. This library is specifically meant for building adaptive layouts and will automatically recompose the layout when your activity's size/orientation changes.

This API gives you the rough size of your width and height (COMPACT, MEDIUM, EXPANDING). This makes it easy to handle devices like foldables and large screen displays.

Here is a simple example implementation I wrote:-

class MainActivity {
    /* ...... */
    setContent {
        val windowSizeClass = calculateWindowSizeClass(this)
        /* .... */
        MyApp(windowWidthSizeClass = windowSizeClass.widthSizeClass, /* .... */ )
    }
}

@Composable
fun MyApp(windowWidthSizeClass: WindowWidthSizeClass, /* ... */) {
    when(windowWidthSizeClass) {
        WindowWidthSizeClass.Expanded -> // orientation is landscape in most devices including foldables (width 840dp+)
        WindowWidthSizeClass.Medium -> // Most tablets are in landscape, larger unfolded inner displays in portrait (width 600dp+)
        WindowWidthSizeClass.Compact -> // Most phones in portrait
    }
}

Here, I can set the layout to a landscape-like view when windowWidthSizeClass is equal to WindowWidthSizeClass.Expanded. I can use the WindowWidthSizeClass.Medium width to optimize my layout for larger devices like tablets and foldables. Lastly, WindowWidthSizeClass.Compact tells me that most mobiles are in portrait and I can update my UI accordingly.

These same enums are also available for the height of the activity but the documentation states -

Most apps can build a responsive UI by considering only the width window size class.

(So far, true for me)

Note that this library is still in alpha and explicitly marked as Experimental so it might change.

Official Guide - https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes#window_size_classes

Example implementation can be found in the JetNews sample app - https://github.com/android/compose-samples/tree/main/JetNews.

Documentation - https://developer.android.com/reference/kotlin/androidx/compose/material3/windowsizeclass/package-summary

Release notes (released in 1.0.0-alpha10, current version - alpha13) - https://developer.android.com/jetpack/androidx/releases/compose-material3#1.0.0-alpha10

1

Both of those can be accessed with the help of LocalConfiguration.current which returns a Configuration object.

For orientation, as you know, there exists a property orientation,

LocalConfiguration.current.orientation

Similarly, there are two other properties as well.

LocalConfiguration.current.screenWidthDp
LocalConfiguration.current.screenHeightDp

This should help your scenario where you want to use it within the signature of the Composable rather than having to do the same inside of it's scope, for example, this can be used in Modifiers to size the composable accordingly.

However, for Modifiers' use for sizing your Composable, I recommend using the fillMaxHeight(/*fraction/*) and fillMaxWidth(/*fraction*/) instead. As would be clear, the fraction is the fraction of space of the parent Composable it should occupy. If the parent Composable is setContent, or if the parent Composable stretches to the entire screen (for example, a Surface using the fillMaxSize() Modifier), then this would be relative to the screen dimensions themselves. So, fillMaxHeight(0.1f) will make the Composable's height equivalent to one tenth of the screen height. You can take the compose-pathway here to learn the basic concepts. It might be not really simple, but may help to build a better foundation for declarative paradigms.

Not the answer you're looking for? Browse other questions tagged or ask your own question.