android.view.View.systemUiVisibility 已弃用。什么是替代品?

Doc*_*ger 70 android kotlin

我已将项目目标 API 版本更新为 30,现在我看到 systemUiVisibility 属性已被弃用。

以下 kotlin 代码是我正在使用的代码,它实际上等效于 Java 中的setSystemUiVisibility方法。

playerView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LOW_PROFILE
            or View.SYSTEM_UI_FLAG_FULLSCREEN
            or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
Run Code Online (Sandbox Code Playgroud)

请让我知道您是否有任何稳定的替代代码来替代这个已弃用的代码。谷歌的建议是使用WindowInsetsController,但我不知道怎么做。

ole*_*234 43

为了兼容性,请使用WindowCompatWindowInsetsControllerCompat。您androidx.core至少需要升级您的 gradle 依赖项,以便在SDK < 30 上1.6.0-alpha03获得支持setSystemBarsBehavior

private fun hideSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(window, false)
    WindowInsetsControllerCompat(window, mainContainer).let { controller ->
        controller.hide(WindowInsetsCompat.Type.systemBars())
        controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }
}

private fun showSystemUI() {
    WindowCompat.setDecorFitsSystemWindows(window, true)
    WindowInsetsControllerCompat(window, mainContainer).show(WindowInsetsCompat.Type.systemBars())
}
Run Code Online (Sandbox Code Playgroud)

您可以WindowInsets通过观看此YouTube 视频了解更多信息

对于在显示屏顶部带有凹槽的设备,您可以将以下内容添加到 v27theme.xml文件中,使 UI 出现在凹槽的任一侧:

<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
Run Code Online (Sandbox Code Playgroud)

您可以在此链接中阅读更多信息:Display Cutout

  • @CoolMind,“mainContainer”是“window.decorView” (13认同)
  • @MoisoniIoan `systemBars()` 包括“所有系统栏。包括 statusBars()、captionBar() 以及 navigationBars(),但不包括 ime()”。请参阅文档:https://developer.android.com/reference/androidx/core/view/WindowInsetsCompat.Type#systemBars() (2认同)

小智 25

TL;DR 片段

需要在 if-else 结构中包装以避免java.lang.NoSuchMethodError: No virtual method setDecorFitsSystemWindows旧 SDK 版本出现异常。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    window.setDecorFitsSystemWindows(false)
} else {
    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
}
Run Code Online (Sandbox Code Playgroud)

包含有关 Android 11 中的插图和全屏模式的完整信息的链接

https://blog.stylingandroid.com/android11-windowinsets-part1/

https://www.youtube.com/watch?v=acC7SR1EXsI


Hum*_*ber 22

我希望它可以帮助你。

以前,在实现边缘到边缘导航或沉浸式模式时,首先要采取的步骤之一是使用 systemUiVisibility 标志来请求应用全屏布局,这个新的 Android 版本弃用了这个字段,以便全屏布局应用程序,您必须在Window类上使用新方法:作为参数setDecorFitsSystemWindows传递false,如下所示。

window.setDecorFitsSystemWindows(false)
Run Code Online (Sandbox Code Playgroud)

WindowInsetsController允许您执行以前通过systemUiVisibility标志控制的操作的类,例如隐藏或显示状态栏或导航栏(分别为隐藏和显示方法)

例如,您可以轻松地显示和隐藏键盘,如下所示:

// You have to wait for the view to be attached to the
// window (otherwise, windowInsetController will be null)
view.doOnLayout {
    view.windowInsetsController?.show(WindowInsets.Type.ime())
    // You can also access it from Window
    window.insetsController?.show(WindowInsets.Type.ime())
}
Run Code Online (Sandbox Code Playgroud)

  • `window.setDecorFitsSystemWindows()` 需要 API 级别 R。如何解决旧 API 级别上的兼容性问题? (9认同)
  • 因此,setDecorFitsSystemWindows 无法用于 API &lt; 30 的全屏显示。感谢您的澄清。 (4认同)
  • 它设置装饰视图是否应适合 WindowInsets 的根级内容视图。似乎它只能与 API 30 一起使用。如果它无法正常工作。进行版本检查 (2认同)

小智 13

从版本开始1.5.0-alpha02androidx.coreWindowCompat.setDecorFitsSystemWindows()

要启用边对边:

WindowCompat.setDecorFitsSystemWindows(window, false)
Run Code Online (Sandbox Code Playgroud)

  • @Geob Google 正在开发 WindowInsetsController 支持库。来源- https://www.youtube.com/watch?v=acC7SR1EXsI (3认同)

ana*_*oli 12

如果有人搜索 Java 版本。

为了Activity

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
    getWindow().setDecorFitsSystemWindows(false);

    if (getWindow().getInsetsController() != null) {
        getWindow().getInsetsController().hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
        getWindow().getInsetsController().setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    }
} else {
    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
}
Run Code Online (Sandbox Code Playgroud)

对于FragmentDialogAlertDialog

if (getDialog() != null && getDialog().getWindow() != null) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        getDialog().getWindow().setDecorFitsSystemWindows(false);
    } else {
        if (getActivity() != null) {
            getDialog().getWindow().getDecorView().setSystemUiVisibility(getActivity().getWindow().getDecorView().getSystemUiVisibility());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Moi*_*nut 7

对于 Java 用户(感谢@James):

//hide system UI
Window window = activity.getWindow();
View decorView = activity.getWindow().getDecorView();

WindowCompat.setDecorFitsSystemWindows(window, false);
WindowInsetsControllerCompat controllerCompat = new WindowInsetsControllerCompat(window, decorView);
controllerCompat.hide(WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.navigationBars());
controllerCompat.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
Run Code Online (Sandbox Code Playgroud)

(编辑)用于BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE在滑动时仅临时显示 sytemBars,BEHAVIOR_SHOW_BARS_BY_SWIPE滑动后将永久显示它们。

来源: https: //developer.android.com/reference/android/view/WindowInsetsController#BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE


Sou*_*chi 6

WindowCompat.setDecorFitsSystemWindows(window, false)
Run Code Online (Sandbox Code Playgroud)

从官方 Android 开发者频道观看本教程。


Cor*_*bie 6

如果您使用Jetpack Compose,请在以下位置使用此方法setContent

@Composable
fun HideSystemUi()
{
    val systemUiController = rememberSystemUiController()

    SideEffect {
        systemUiController.isSystemBarsVisible = false
    }
}
Run Code Online (Sandbox Code Playgroud)

不要忘记将其添加到您的应用程序build.gradle文件中(如有必要,请调整版本):

implementation "com.google.accompanist:accompanist-systemuicontroller:0.17.0"
Run Code Online (Sandbox Code Playgroud)

尽管您可能想查看源代码,但可以在此处找到该文档。


Kis*_*nki 5

2022 年 Kotlin 代码官方解决方案:

val windowInsetsController =
            ViewCompat.getWindowInsetsController(window.decorView) ?: return
        // Configure the behavior of the hidden system bars
        windowInsetsController.systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        // Hide both the status bar and the navigation bar
        windowInsetsController.hide(WindowInsetsCompat.Type.systemBars())
Run Code Online (Sandbox Code Playgroud)

来源: https: //developer.android.com/training/system-ui/immersive#kotlin

  • 不幸的是,这对我不起作用,但“WindowInsetsControllerCompat(window, window.decorView).hide(WindowInsetsCompat.Type.statusBars())”工作正常。我在这里可能做错了什么? (3认同)