我试图在Android 10中隐藏状态栏.我已经阅读了很多类似问题的答案,但它们不适用于我的设备.目标是将状态栏的空间用作应用程序视图的一部分:

enter image description here

下面描述的一些解决方案可以在emulator上使用,但不能在我的物理设备上使用(Redmi Note 10,API版本29).

如果您有任何建议,我将不胜感激.

What I have tried:
  • 使用不同的预定义样式,如@android:style/Theme.NoTitleBar.Fullscreen等.
  • 使用不同的样式属性,包括:android:windowFullscreenfitsSystemWindows等.
  • 使用setSystemUiVisibility设置程序代码中的不同样式,包括SYSTEM_UI_FLAG_FULLSCREENSYSTEM_UI_FLAG_IMMERSIVE_STICKYSYSTEM_UI_FLAG_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_FULLSCREENSYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATIONSYSTEM_UI_FLAG_LAYOUT_STABLE.
  • 使用clearFlagsaddFlagssetFlags添加和删除不同的标志.
  • 使用setStatusBarColor将状态栏 colored颜色 设置为透明.
  • 使用requestWindowFeature请求不同的功能.
  • 将布局顶部填充更改为负值.
  • 通过定义applyTopWindowInsetsForViewonApplyWindowInsets个函数使用插入.
What I've managed to do.

我成功地得到了两个结果,但这两个结果对我都不好.

  1. 半透明状态栏.

enter image description here

  1. 完全黑色的状态栏,不占用应用程序视图的空间.

enter image description here

UPDATE 10 May 2022:

根据以下答案,不可能在API 29或更早版本上使用WindowInsetsController:How do I hide the status bar in my Android 11 app?

SOLUTION 1

@Zain人提议.

活动:

protected void onCreate(Bundle savedInstanceState) {
    ...
    WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
    WindowInsetsControllerCompat windowInsetsCompat = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());
    windowInsetsCompat.hide(WindowInsetsCompat.Type.statusBars());        
    windowInsetsCompat.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
    ...

主题xml:

<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>

SOLUTION 2

活动:

protected void onCreate(Bundle savedInstanceState) {
    ...        
    getWindow().getDecorView().setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
            | 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_LOW_PROFILE
    );        
    ...

主题xml:

<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>

推荐答案

你需要在应用程序中边到边显示内容(Documentation reference)

Step 1:用法:WindowCompat.setDecorFitsSystemWindows(window, false)

这是确保应用程序边缘到边缘的主要步骤,也就是说,使用显示器的整个宽度和高度进行布局.使用WindowCompat.设置DecorfitsSystemWindows(window,false)以在系统栏后面布局应用程序,如以下代码示例所示:

Step 2:使用WindowInsetsControllerCompat隐藏状态栏:

    WindowInsetsControllerCompat(window, window.decorView).apply {
        // Hide the status bar
        hide(WindowInsetsCompat.Type.statusBars())
        // Allow showing the status bar with swiping from top to bottom
        systemBarsBehavior =
            WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
    }

Step 3:从步骤1开始,底部的活动内容将被底部导航栏遮挡;然后,您需要使用WindowInsetsListener将活动根布局的底部边距调整为导航栏的高度:

锅炉:

// root layout of your activity
val root = findViewById<ConstraintLayout>(R.id.root)
ViewCompat.setOnApplyWindowInsetsListener(
    root
) { view: View, windowInsets: WindowInsetsCompat ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
    view.layoutParams = (view.layoutParams as FrameLayout.LayoutParams).apply {
        // draw on top of the bottom navigation bar
        bottomMargin = insets.bottom
    }

    // Return CONSUMED if you don't want the window insets to keep being
    // passed down to descendant views.
    WindowInsetsCompat.CONSUMED
}

Java :

WindowInsetsControllerCompat windowInsetsCompat = new WindowInsetsControllerCompat(getWindow(), getWindow().getDecorView());

windowInsetsCompat.hide(WindowInsetsCompat.Type.statusBars());
windowInsetsCompat.setSystemBarsBehavior(WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);

// root layout of your activity
ConstraintLayout root = findViewById(R.id.root);

ViewCompat.setOnApplyWindowInsetsListener(
        root
        , (view, windowInsets) -> {
            Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) view.getLayoutParams();
            params.bottomMargin = insets.bottom;
            return WindowInsetsCompat.CONSUMED;
        });

Step 4:最后,确保在应用程序的主题中允许绘制剪切区域:

<item name="android:windowLayoutInDisplayCutoutMode">always</item>

Android相关问答推荐

为什么R8不混淆某些类?

避免在按下肯定按钮时自动取消AlertDialog

如何删除Jetpack Compose中的Textfield底线

如何使用Jetpack Compose实现此底表?

如何在初始合成期间在可组合函数中调用/获取远程API中的数据[防止无限重组]

Jetpack Compose-如何在进入新产品线之前删除单词?

触发PurchasesUpdatedListener回调时,billingClient.launchBillingFlow之前设置的成员变量丢失

在c中更新MVVMCross中TextView的Alpha#

Visual Studio 2022,毛伊岛,Android Emulator:无法更改内存量

如何检测低性能 Android 设备进行条件动画渲染?

Jetpack Compose 使用 SavedStateHandle 发送返回结果不适用于 ViewModel 中注入的 SavedStateHandle

Android 不在后台更新位置

使用不同的gradle文件导入外部库

Android 构建失败:找不到 flexbox2.0.1.aar

React-native 3D对象渲染

Jetpack Compose 部分或开放侧边框

如何在 Android 应用程序未激活/未聚焦时显示视图?

Int 传递给 Intent 但Android工作室说我传递了一个字符串

Android Compose:LazyColumn 和 Column with verticalScroll 的区别

我的自定义视图没有显示我应该如何修复它?