ViewCompat.getWindowInsetsController已过时 - 应使用哪个替代方案?

21

在升级至 Android Gradle 插件版本 7.2.2 后,Jetpack Compose 项目的默认 Theme.kt 文件会出现警告:

ViewCompat.getWindowInsetsController is deprecated

这个警告来自于项目脚手架中提供的默认实现:

/* snip */
val view = LocalView.current
    if (!view.isInEditMode) {
        SideEffect {
            (view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
            ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = darkTheme // <--- This triggers a deprecation warning
        }
    }
文档建议使用WindowCompat.getInsetsController代替,但该函数需要访问viewwindow。是否有一种简单的方法来解决此警告而不会忽略它?
1个回答

28

这里提供完整的必须更改内容

if 代码片段仅存在于Android Studio中的组件预览中,因为在那里永远没有可用的Activity可供附加!(当您实际运行应用程序时,view不会处于编辑模式-因此只有在实际情况下运行内部语句)。

由于逻辑上仅在真实应用程序中执行,我们可以进行一些类型转换来检索当前window,并假定view.contextActivity。如果是Activity,则可以访问currentWindow属性,并将其用作推荐方法的window参数。

因此,我们最终得到以下代码-其中进行了一些额外的重构以减少代码重复-将当前视图的上下文转换为Activity并进行适当的设置:

@Composable
fun YourAppTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    // Dynamic color is available on Android 12+
    dynamicColor: Boolean = true,
    content: @Composable () -> Unit
) {
    val colorScheme = pickColorScheme(dynamicColor, darkTheme)
    val view = LocalView.current

    if (!view.isInEditMode) {
        /* getting the current window by tapping into the Activity */
        val currentWindow = (view.context as? Activity)?.window
            ?: throw Exception("Not in an activity - unable to get Window reference")

        SideEffect {
            /* the default code did the same cast here - might as well use our new variable! */
            currentWindow.statusBarColor = colorScheme.primary.toArgb()
            /* accessing the insets controller to change appearance of the status bar, with 100% less deprecation warnings */
            WindowCompat.getInsetsController(currentWindow, view).isAppearanceLightStatusBars =
                darkTheme
        }
    }

    MaterialTheme(
        colorScheme = colorScheme,
        typography = Typography,
        content = content
    )
}

1
为什么要抛出异常? - David
在所有预期的“正常”情况下,Activity及其属性将可供此例程访问,因此我选择了异常处理。如果以某种方式我们不处于编辑模式,并且应用程序中没有可用的Activity,则表示出现了问题,我们无法保证主题内的任何内容都会按预期运行。 - Alves RC

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