【问题标题】:On android 11 status bar doesn't get hide在 android 11 上,状态栏不会隐藏
【发布时间】:2022-01-27 00:58:24
【问题描述】:

此代码使状态栏在 Android 10 及之前版本上透明

//makes actionbar transparent activity.window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

但是在 android 11 中它并没有消失

Android 11

Android 8

我的 styles.xml 文件如下所示

<resources xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">
<style name="DropitTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>


    <style name="MyThemeOverlay_Toolbar" parent="ThemeOverlay.MaterialComponents.Toolbar.Primary">
        <!-- color used by navigation icon and overflow icon -->
        <item name="colorOnPrimary">@color/colorPrimary</item>
    </style>

    <style name="Toolbar_text_style" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
        <!-- color used by navigation icon and overflow icon -->
        <item name="android:textSize">@dimen/textSizeHuge</item>
    </style>
</resources>

清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.app">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/DropitTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <meta-data
            android:name="preloaded_fonts"
            android:resource="@array/preloaded_fonts" />
    </application>

</manifest>

最后是themes.xml

<resources xmlns:tools="http://schemas.android.com/tools">
    <!-- Base application theme. -->
    <!-- Base application theme. -->
    <style name="Theme.Dropit" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
        <!-- Primary brand color. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryVariant">@color/colorSecondary</item>
        <item name="colorOnPrimary">@color/white</item>
        <!-- Secondary brand color. -->
        <item name="colorSecondary">@color/colorSecondary</item>
        <item name="colorSecondaryVariant">@color/colorSecondaryLight</item>
        <item name="colorOnSecondary">@color/white</item>
        <!-- Status bar color. -->
        <item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
        <!-- Customize your theme here. -->
    </style>
</resources>

正如您在 Manifest 中看到的,我使用的是样式主题而不是主题主题。那么我该如何解决这个问题呢?

【问题讨论】:

  • 您好,我在 Android 11 上遇到了同样的问题。(模拟器 Pixel 4 和物理设备)。您介意将您的styles.xmlthemes.xml 文件分享给其他想帮助您的人吗?
  • 嘿@dumbfingers 感谢您的回复,我添加了您要求的两个文件

标签: android android-layout


【解决方案1】:

我遇到了同样的问题并找出了这个解决方案。

val controller = requireActivity().window.insetsController
        controller?.systemBarsBehavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
        controller?.hide(WindowInsets.Type.statusBars())

如果您从 Activity 调用它,则不需要 requireActivity()。 我遇到了一些问题,在某些片段上它开始重置为标准状态栏,所以我在每个 onCreate() 上调用它并修复它。

【讨论】:

  • 通过上面的代码状态栏隐藏并在滑动时显示但状态栏显示为黑暗,我们怎样才能使其透明或与应用程序相同的颜色。
  • @swati 可以设置 BEHAVIOR_SHOW_BARS_BY_SWIPE 或 BEHAVIOR_SHOW_BARS_BY_TOUCH,但是需要在 onTouch 事件后手动隐藏。
【解决方案2】:

我找到了兼容的sollution 来设置导航栏和状态栏透明。
如果您使用它来实现状态栏透明,请确保在代码中删除fitsSystemWindow=true,否则它将无法正常工作。

如果你只想设置状态栏透明而不是导航栏:

  1. 添加

    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      WindowCompat.setDecorFitsSystemWindows(window, false)
    }
    
  2. 设置&lt;item name="android:statusBarColor"&gt;@android:color/transparent&lt;/item&gt; 你的应用主题

  3. 将底部插图添加到主视图容器。在我的情况下 frameLayout,显示片段

    ViewCompat.setOnApplyWindowInsetsListener(binding.main_container) {
                                                                       view, windowInsets->
                val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
    
                view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
                    bottomMargin = insets.bottom
                }
                WindowInsetsCompat.CONSUMED
            }
    

【讨论】:

    【解决方案3】:

    对于 notch display屏幕内的摄像头,此代码对我有用。 我检查了红米note10:

        private fun hideSystemUI() {
        window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN
                or View.SYSTEM_UI_FLAG_LOW_PROFILE
                or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                or View.SYSTEM_UI_FLAG_IMMERSIVE
                or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            window.attributes.layoutInDisplayCutoutMode =
                WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
        }
    }
    

    super.onCreate(savedInstanceState)之后立即调用它

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        hideSystemUI()
        setContentView(R.layout.activity_main)
        //do you work
    }
    

    【讨论】:

    • 这些标志在 Android 11 上已弃用。OP 询问的是 Android 11,而不是 Android 10。
    • @WachidSusilo 我在上面提到过。我检查了 Redmi(Android 11),这段代码对我有用。很抱歉已弃用