Jetpack Compose:如何支持所有屏幕尺寸的最佳方式是什么?

4

我在 Google 上搜索了多种使用 Jetpack Compose 在 Android 上支持多个屏幕尺寸的方法,最终找到了 Google 的文档: https://developer.android.com/guide/topics/large-screens/support-different-screen-sizes#compose

enum class WindowSizeClass { COMPACT, MEDIUM, EXPANDED }

@Composable
fun Activity.rememberWindowSizeClass() {
    val configuration = LocalConfiguration.current
    val windowMetrics = remember(configuration) {
        WindowMetricsCalculator.getOrCreate()
            .computeCurrentWindowMetrics(this)
    }
    val windowDpSize = with(LocalDensity.current) {
        windowMetrics.bounds.toComposeRect().size.toDpSize()
    }
    val widthWindowSizeClass = when {
        windowDpSize.width < 600.dp -> WindowSizeClass.COMPACT
        windowDpSize.width < 840.dp -> WindowSizeClass.MEDIUM
        else -> WindowSizeClass.EXPANDED
    }

    val heightWindowSizeClass = when {
        windowDpSize.height < 480.dp -> WindowSizeClass.COMPACT
        windowDpSize.height < 900.dp -> WindowSizeClass.MEDIUM
        else -> WindowSizeClass.EXPANDED
    }

    // Use widthWindowSizeClass and heightWindowSizeClass
}

但这可能会对ldpi屏幕构成问题,那么该如何存储这些变量呢?我需要像以前一样在所有密度下的dimen文件夹中存储dimens值吗?因为例如,在400dp屏幕上的图像在ldpi屏幕上可能看起来非常大(约120dp)。

我对Jetpack Compose还很陌生,感觉有些困惑。非常感谢您的帮助。


dips是一个固定单位,不受屏幕密度影响。如果您想根据屏幕大小/方向进行布局更改,则与用于布局/尺寸等的xml资源系统不同,Jetpack Compose没有提供结构来选择基于运行时环境的视图/资源/布局。所引用的文档似乎令人困惑,它从Compose函数开始,然后回到使用xml系统,使用约束布局来创建响应式布局的最佳方法是什么?令人困惑吗? - Mark
3个回答

2
你可以使用库https://github.com/GetStream/butterfly或创建

rememberWindowSizeClass.kt

记住窗口大小类
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
    )
}

In

MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            val windowSize = rememberWindowSizeClass()
            when (windowSize.widthWindowSizeClass) {
                is WindowSizeClass.WindowType.COMPACT -> {
                    AppScreenCompact()
                }
                is WindowSizeClass.WindowType.MEDIUM -> {
                    AppScreenMedium()
                }
                else -> {
                    AppScreenExpanded()
                }
            }
        }
    }
}

如需更多信息,请参考文档示例


0

上面的代码只是一个例子。您可以根据这个想法创建自己的代码以满足您的需求。

可以使用资源系统保存尺寸,但我真的看不出有什么理由这样做。如果您的图像是200dp,那么它就是200dp。DP是动态的。是的,在小屏幕上,200dp会更大,但这应该,因为用户实际上应该看到图像的内容。

您的应用程序布局在不同的屏幕大小和设置上不会破裂,这是另一个与Compose理论不太相关的问题。您只需要以一种方式设计您的布局,使它们对字体/ dpi大小变化不敏感,这意味着温和的字体/ dpi大小变化不应该能够破坏布局。

除此之外,您可以为与您的标准组合不同的屏幕配置编写不同的组合。


0
使用Jetmagic。它的设计是将您的可组合项视为资源,就像旧的视图系统处理您的xml布局一样。它支持所有由资源文件夹支持的配置限定符,包括屏幕大小和屏幕密度限定符。
使用Jetmagic,根据设备配置选择您的可组合项,并在运行时更改配置(例如设备方向更改)时重新选择不同的可组合项。
该框架包括一个演示应用程序,并且有一篇关于它的详细文章在Medium上。

https://github.com/JohannBlake/Jetmagic

Jetmagic是一种比使用WindowSizeClass更优越的解决方案。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接