在安卓11上,状态栏无法隐藏。

4

该代码使得Android 10及之前版本的状态栏透明

//使操作栏透明 activity.window.setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS, WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS)

然而在Android 11上它并不能消失

Android 11

这是在Android 11上的效果

Android 8

这是在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>

从清单中可以看到,我正在使用样式主题而不是主题主题。那么我该如何解决这个问题?


嗨,我在Android 11上遇到了同样的问题(模拟器Pixel 4和实体设备都有)。你介意分享你的styles.xmlthemes.xml文件给其他想帮助你的人吗? - dumbfingers
嘿@dumbfingers,谢谢你的回复,我已经添加了你要求的两个文件。 - Sebastián Fernández
3个回答

3

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

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

如果您从 Activity 中调用它,则不需要 requireActivity()。我曾经在某些片段中遇到问题,其中它开始重置为标准状态栏,因此我在每个 onCreate() 上调用它,这样就解决了问题。

1
通过以上代码,可以在滑动时隐藏和显示状态栏,但是状态栏会以深色显示,如何使它们透明或与应用程序相同颜色呢? - swati vishnoi
1
@swati 你可以设置 BEHAVIOR_SHOW_BARS_BY_SWIPE 或 BEHAVIOR_SHOW_BARS_BY_TOUCH,但是在 onTouch 事件之后你需要手动隐藏它。 - Matej Đuroković

1

对于刘海屏屏幕内置摄像头,这段代码对我有效。我在红米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。 - Wachid Susilo
@WachidSusilo,如上所述。我在Redmi(Android 11)上进行了检查,这段代码对我有效。对于已弃用的部分,我感到抱歉。 - Faisal ur Rehman

1
我已经找到了一个兼容的解决方案,可以使导航栏和状态栏透明。
请确保在您的代码中删除了fitsSystemWindow=true,如果您使用它来实现状态栏透明度,否则它将无法正常工作。
如果您只想设置状态栏透明而不是导航栏:
  1. add

    override fun onCreate(savedInstanceState: Bundle?) {
      super.onCreate(savedInstanceState)
      WindowCompat.setDecorFitsSystemWindows(window, false)
    }
    
  2. Set <item name="android:statusBarColor">@android:color/transparent</item> in your app theme

  3. Add bottom inset to the main view container. In my case it's frameLayout, which displays fragments

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

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