Android 11 上的沉浸式全屏

Leo*_*tev 23 java android android-layout

之前,要启用沉浸式全屏模式,您必须使用setSystemUiVisibility,如下所示:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
            | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
            | View.SYSTEM_UI_FLAG_FULLSCREEN
            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
Run Code Online (Sandbox Code Playgroud)

从 API 30 开始,它已被弃用,那么解决方法是什么?

ole*_*234 26

为了兼容性,请使用WindowCompatWindowInsetsControllerCompat。您androidx.core至少需要将您的 gradle 依赖项升级到 ,1.6.0-alpha03以便setSystemBarsBehavior对 SDK < 30 的支持。mainContainerConstraintLayout我活动中的顶级。

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 视频了解更多信息

编辑:

我之前没有在这个答案中考虑过显示屏切口或显示屏内摄像头。在应用程序主题样式中,我添加了以下内容以在切口上方显示我的内容(在纵向模式下显示在屏幕顶部):

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

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

  • 我认为你的意思是控制器兼容性的“1.5.0-alpha05” (4认同)
  • 我发现在某些使用此 alpha 库的设备上设置“systemBarsBehavior”可能存在问题。请参阅错误报告:https://issuetracker.google.com/issues/173203649#comment2 *请务必给问题加注星标以获得更多关注 (2认同)

Leo*_*tev 20

正如文档所建议的那样,您应该使用WindowInsetsController.

getWindow().setDecorFitsSystemWindows(false);
WindowInsetsController controller = getWindow().getInsetsController();
if (controller != null) {
    controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
    controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
}
Run Code Online (Sandbox Code Playgroud)

  • 好的,我尝试了这个,但这需要最低 api 级别 30。所以我的问题是 - “对于低于 30 级的 api 级别应该实现什么?” (2认同)
  • @MohitYadav 你通常用 if 来做,例如 `if (Build.VERSION.SDK_INT &lt; 30) { ... 这里是旧设备的版本 ... } else { 这里是新版本 }` (2认同)

Rob*_*hah 7

对于弃用,您可以尝试以下代码。为我工作。

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        final WindowInsetsController controller = getWindow().getInsetsController();

        if (controller != null)
            controller.hide(WindowInsets.Type.statusBars());
    }
    else {
        //noinspection deprecation
                getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_IMMERSIVE
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    }
Run Code Online (Sandbox Code Playgroud)


Pan*_*iya 7

对于全屏

隐藏状态栏

private void hideSystemBars() {
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
    WindowInsetsControllerCompat windowInsetsController = ViewCompat.getWindowInsetsController(getWindow().getDecorView());
    if (windowInsetsController == null) {
        return;
    }
    // Configure the behavior of the hidden system bars
    windowInsetsController.setSystemBarsBehavior(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)

显示状态栏

private void showSystemBars() {
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
    WindowInsetsControllerCompat windowInsetsController = ViewCompat.getWindowInsetsController(getWindow().getDecorView());
    if (windowInsetsController == null) {
        return;
    }
    // Configure the behavior of the hidden system bars
    windowInsetsController.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    // Hide both the status bar and the navigation bar
    windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
}
Run Code Online (Sandbox Code Playgroud)

用于全屏模式下的顶部相机切割

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


Web*_*.11 6

这对我有用,混合了两个答案:

首先创建方法:

private void setFullScreen(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        getWindow().setDecorFitsSystemWindows(false);
        WindowInsetsController controller = getWindow().getInsetsController();
        if(controller != null) {
            controller.hide(WindowInsets.Type.statusBars() | WindowInsets.Type.navigationBars());
            controller.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
        }
    }
    else {
        //noinspection deprecation
        getWindow().getDecorView().setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                        | View.SYSTEM_UI_FLAG_IMMERSIVE
                        | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                        | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                        | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在创建时只需在 setContentView 之后调用它,如下所示:

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_menu);
        setFullScreen();
    }
Run Code Online (Sandbox Code Playgroud)

它就像一个魅力:D