You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在@Preview可组合函数中使用calculateWindowSizeClass(activity = this)

如何在@Preview可组合函数中使用calculateWindowSizeClass(activity = this)

嘿,我懂你碰到的难题了——在@Preview可组合函数里想用calculateWindowSizeClass确实有点棘手,毕竟Preview环境里根本没有真实的Activity实例,直接传this肯定会报错对吧?别慌,我给你几个实用的解决办法,帮你搞定预览问题:

方法1:手动创建WindowSizeClass模拟不同设备尺寸

既然Preview里拿不到真实的Activity,那我们就直接手动构造WindowSizeClass实例,模拟不同设备的尺寸就行。这样你还能精准控制要预览的设备类型,比如手机、平板或者大屏设备。

示例代码:

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Preview(showBackground = true, showSystemUi = true, backgroundColor = 0xffffff)
@Composable
private fun BottomNavigationBarPreview() {
    // 模拟普通手机的紧凑宽度尺寸类
    val windowSizeClass = WindowSizeClass.calculateFromSize(
        size = DpSize(width = 360.dp, height = 640.dp)
    )
    
    // 把构造好的windowSizeClass传给你的BottomNavigationBar
    BottomNavigationBar(windowSizeClass = windowSizeClass)
}

你可以随便调整widthheight的数值,比如想预览平板效果就改成width = 1200.dp,非常灵活。

方法2:用PreviewParameter一次性预览多种尺寸

如果你想同时预览多种尺寸下的UI效果,不用写多个Preview函数,用PreviewParameter就能搞定。先写一个参数提供者,然后在Preview函数里接收即可:

首先定义一个PreviewParameterProvider:

class WindowSizeClassProvider : PreviewParameterProvider<WindowSizeClass> {
    @OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
    override val values = sequenceOf(
        // 紧凑宽度(手机)
        WindowSizeClass.calculateFromSize(DpSize(360.dp, 640.dp)),
        // 中等宽度(折叠屏/小平板)
        WindowSizeClass.calculateFromSize(DpSize(800.dp, 1280.dp)),
        // 扩展宽度(大屏平板/桌面)
        WindowSizeClass.calculateFromSize(DpSize(1200.dp, 1920.dp))
    )
}

然后修改你的Preview函数:

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Preview(showBackground = true, showSystemUi = true, backgroundColor = 0xffffff)
@Composable
private fun BottomNavigationBarPreview(
    @PreviewParameter(WindowSizeClassProvider::class) windowSizeClass: WindowSizeClass
) {
    BottomNavigationBar(windowSizeClass = windowSizeClass)
}

这样Android Studio会自动生成三个预览窗口,分别对应三种不同的尺寸类效果,一次性看全所有场景。

方法3:封装兼容Preview的通用获取逻辑

如果你的Composable既要在真实运行环境使用,又要支持Preview,那可以封装一个通用的函数,自动判断当前环境并返回对应的WindowSizeClass:

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Composable
fun rememberWindowSizeClass(): WindowSizeClass {
    val context = LocalContext.current
    // LocalInspectionMode.current可以判断是否处于Preview环境
    val isPreview = LocalInspectionMode.current
    
    return if (isPreview) {
        // Preview环境下返回默认的紧凑尺寸类,你也可以改成其他默认值
        WindowSizeClass.calculateFromSize(DpSize(360.dp, 640.dp))
    } else {
        // 真实环境下从Activity获取
        calculateWindowSizeClass(activity = context as Activity)
    }
}

之后不管是在真实的Composable里还是Preview里,都直接用这个函数就行:

@Composable
fun BottomNavigationBar() {
    val windowSizeClass = rememberWindowSizeClass()
    // 这里写你的UI逻辑,根据windowSizeClass调整布局
}

@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
@Preview(showBackground = true, showSystemUi = true, backgroundColor = 0xffffff)
@Composable
private fun BottomNavigationBarPreview() {
    BottomNavigationBar()
}

这样就不用在Preview里单独处理,代码复用性也更高。

备注:内容来源于stack exchange,提问作者Ali Mohammadzadeh

火山引擎 最新活动