使用android jetpack compose支持不同的屏幕尺寸,还支持桌面等可折叠设备姿势
我想支持手机、平板电脑、可折叠设备和电视等设备。下面的代码可以达到这个目的吗?
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()
}
此代码适用于可折叠设备,特别是桌面上的可折叠设备姿势?
是否建议在手机上安装 BottomNavigation、在平板电脑上安装 Nav Rail、在导航抽屉或电视上安装
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您包含的代码将帮助您支持不同尺寸的设备,但它不会检测可折叠姿势。为此,您需要使用 Jetpack Window Manager 库来访问
FoldingFeature
信息 (API 参考)。Jetcaster 官方 Compose 示例提供了如何检测桌面/书籍模式的示例 (MainActivity, WindowInfoUtil),但还需要注意的是,某些可折叠设备具有完全独立的屏幕(即使是平放的)。为了支持所有类型的可折叠项,除了
FoldingFeature.state
之外,我建议检查FoldingFeature.isSeparating
属性。有关可折叠支持的更多信息,您可以查看以下文档:
对于导航,我不熟悉电视的指南,但对于其他设备,我认为建议取决于当前的窗口大小类别。 BottomNavigation 最适合
COMPACT
宽度(大多数手机),而 NavigationRail 更适合MEDIUM
和EXPANDED
宽度(平板电脑和较大的可折叠设备)。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 toFoldingFeature.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 forMEDIUM
andEXPANDED
widths (tablets and larger foldables).