Reputation: 2589
I want to support devices like phone, tablets, foldables and tv. Will the following code work for that purpose ?
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val windowSize = rememberWindowSizeClass()
when (windowSize.widthWindowSizeClass) {
is WindowSizeClass.WindowType.COMPACT -> {
CompactActivityUi()
/*TODO(reason = "Ui for COMPACT window")*/
}
is WindowSizeClass.WindowType.MEDIUM -> {
/*TODO(reason = "Ui for Medium window")*/
}
else -> {
/*TODO(reason = "Ui for EXPANDED window")*/
}
}
}
}
}
@Composable
fun CompactActivityUi() {
AppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
}
}
}
data class WindowSizeClass(
val widthWindowSizeClass: WindowType,
val heightWindowSizeClass: WindowType,
val widthWindowDpSize: Dp,
val heightWindowDpSize: Dp
) {
sealed class WindowType {
object COMPACT : WindowType()
object MEDIUM : WindowType()
object EXPANDED : WindowType()
}
}
@Composable
fun Activity.rememberWindowSizeClass(): WindowSizeClass {
val configuration = LocalConfiguration.current
val windowMetrics = remember(configuration) {
WindowMetricsCalculator.getOrCreate()
.computeCurrentWindowMetrics(activity = this)
}
val windowDpSize = with(LocalDensity.current) {
windowMetrics.bounds.toComposeRect().size.toDpSize()
}
return WindowSizeClass(
widthWindowSizeClass = when {
windowDpSize.width < 0.dp -> throw IllegalArgumentException("Dp value cannot be negative")
windowDpSize.width < 600.dp -> WindowSizeClass.WindowType.COMPACT
windowDpSize.width < 840.dp -> WindowSizeClass.WindowType.MEDIUM
else -> WindowSizeClass.WindowType.EXPANDED
},
heightWindowSizeClass = when {
windowDpSize.height < 0.dp -> throw IllegalArgumentException("Dp value cannot be negative")
windowDpSize.height < 480.dp -> WindowSizeClass.WindowType.COMPACT
windowDpSize.height < 900.dp -> WindowSizeClass.WindowType.MEDIUM
else -> WindowSizeClass.WindowType.EXPANDED
},
widthWindowDpSize = windowDpSize.width,
heightWindowDpSize = windowDpSize.height
)
}
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
CompactActivityUi()
}
Will this code work for foldables, specially foldables in tabletop posture?
Is it recommended to have BottomNavigation on phone, Nav Rail on tablet and Navigation Drawer or T.V.
Upvotes: 1
Views: 2751
Reputation: 71
The code you included will help you support devices of different sizes, but it won't detect foldable postures. To do that, you need to use the Jetpack Window Manager library to access FoldingFeature
information (API reference).
The Jetcaster official Compose sample has an example of how to detect tabletop/book mode (MainActivity, WindowInfoUtil), but it's also important to note that some foldable devices have completely separate screens (even when flat). To support all kinds of foldables, I would recommend checking the FoldingFeature.isSeparating
property in addition to FoldingFeature.state
.
For more information about foldable support, you can check out these docs:
For navigation, I'm not familiar with the guidance for TV, but for other devices I think the recommendations depend on the current window size class. BottomNavigation is best for COMPACT
width (most phones), while NavigationRail is better for MEDIUM
and EXPANDED
widths (tablets and larger foldables).
Upvotes: 3