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.
-
Based on the discussion I've read so far, this still seems to be a work in progress. There are some ideas floated around in this thread if you are curious to see how they are thinking about it - kotlinlang.slack.com/archives/CJLTWPH7S/p1565158290118600– Vinay GabaCommented Dec 2, 2019 at 5:30
4 Answers
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
}
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 -> {
/* ... */
}
}
}
-
1Thanks. 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
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
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 Modifier
s' 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.