透明状态栏不适用于 windowTranslucentNavigation="false"

Posted

技术标签:

【中文标题】透明状态栏不适用于 windowTranslucentNavigation="false"【英文标题】:Transparent status bar not working with windowTranslucentNavigation="false" 【发布时间】:2015-04-02 02:12:21 【问题描述】:

我正在开发一个Activity,我需要在其中使导航栏不透明,并且在运行 5.0+(API 21+)的设备上使状态栏透明。下面是我使用的样式,以及对我的问题的解释。

AppTheme 扩展 Theme.AppCompat.Light.NoActionBar

<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowActionBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@color/welbe_red_transparent</item>

FullscreenTheme 扩展 AppTheme

<item name="android:windowNoTitle">true</item>
<item name="android:statusBarColor">@color/transparent</item>
<item name="android:windowTranslucentNavigation">true</item>

这使应用看起来像这样

如果我删除android:windowTranslucentNavigation 样式,或将其设置为Fullscreen 中的false,它会修复导航栏问题。问题是状态栏完全变成白色,而不是保持透明并显示其背后的内容。

我曾尝试在我的布局中使用fitsSystemWindow="true",但它并没有解决问题。有人知道为什么会这样吗?

【问题讨论】:

我有点不清楚你真正想要什么:导航栏默认、透明状态栏和你在状态栏后面的背景。对吗? 是的,这正是我想要展示的。当我关闭android:windowTranslucentNavigation时,背景停止在状态栏后面延伸。 【参考方案1】:

android:windowTranslucentNavigation 做了一件android:statusBarColor 没有做的事情,那就是请求SYSTEM_UI_FLAG_LAYOUT_STABLESYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 标志。

这些是您需要请求才能在状态栏后面绘制的。

在您的ActivityonCreate 中请求他们:

getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

或者,您也可以简单地设置您的应用程序主题背景,它也会在您的状态栏后面弹出。

更多信息here。

【讨论】:

正是我需要的!谢谢你。文档说“根据需要调整窗口标志”,但没有提及哪些标志...... 经过大量搜索和数小时的努力,我终于在这里找到了答案。非常感谢。作为附加说明,我们应该删除 fitsSystemWindows 以使其正常工作。【参考方案2】:

据我所知,在低于 19 的 API 上设置状态栏的颜色没有合适的方法。

对于 API 19+,您可以将与 windowTranslucentNavigation 类似的属性用于状态栏:

<item name="android:windowTranslucentStatus">true</item>

注意事项:

你得到一个白色状态栏的原因是因为

<item name="android:statusBarColor">@color/transparent</item> 

some hacks 可以在特定制造商的设备上运行,但我自己不会使用它们。

【讨论】:

我了解如何以向后兼容的方式实现这一点,我在 19+21+ 上使用了不同的样式。背景应该在21+ 上的透明状态栏下方,但是我与 AppCompat 一起使用的设置组合在某处破坏了该功能。这个答案实际上并没有回答问题。 @AustynMahoney “我需要使导航栏不透明,同时在 5.0+ 上保持状态栏透明” - 完成。 “我还需要这个才能在 minSdkVersion 14+ 上工作” - 不能工作,只有 19+。那你的问题是什么? 问题还是一样。为什么关闭android:windowTranslucentNavigation会阻止背景完全适合系统窗口(状态栏为白色的原因)。我不需要透明度在 14+ 上工作(我知道这是不可能的),我只是指出解决方案需要使用 AppCompat 主题/样式来保持向后兼容性。 @AustynMahoney 好吧,我确实说过 statusBar 是白色的,因为您正在设置透明颜色,您是否尝试将其删除? 如果您建议删除透明颜色,我不确定您是否理解我在这里尝试执行的操作。 “您也可以自己在状态栏后面绘制。例如,如果您想在照片上透明地显示状态栏,并使用微妙的深色渐变以确保白色状态图标可见。为此,请设置 android:statusBarColor属性为@android:color/transparent 并根据需要调整窗口标志。” - developer.android.com/training/material/theme.html【参考方案3】:

我为此奋斗了 3 个多小时。将所有内容包装在 CoordinatorLayout 中,它似乎是唯一一个注意 fitSystemWindow="true" 或 "false"

这是我的主要活动片段

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/content_main"
    android:layout_
    android:layout_>

    <include layout="@layout/layout_google_map"/>

    <include layout="@layout/layout_toolbar_transparent"/>

    <include layout="@layout/layout_action_buttons"/>

    <include layout="@layout/layout_bottom_sheet"/>

</android.support.design.widget.CoordinatorLayout>

这是我的工具栏布局

<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    android:fitsSystemWindows="true">

    <android.support.v7.widget.Toolbar
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/toolbar"
        android:layout_
        android:layout_
        android:background="@android:color/transparent"
        android:theme="@style/ToolbarTheme"
        app:popupTheme="@style/AppTheme.PopupOverlay">

        <android.support.v7.widget.AppCompatImageView
            android:layout_
            android:layout_
            android:layout_centerHorizontal="true"
            android:layout_gravity="center"
            android:adjustViewBounds="true"
            app:srcCompat="@drawable/ic_fynd_logo_red"/>

    </android.support.v7.widget.Toolbar>
</android.support.design.widget.CoordinatorLayout>

如您所见,我的片段布局使 google 地图绘制在状态栏下方。

我有一个公司徽标所在的操作栏。

其他 ui 按钮“layout_action_buttons”也包裹在 Coordinator 布局中,因此 fitSystemsWindows 可以正常工作。

检查一下。

【讨论】:

你能在谷歌地图上显示指南针按钮的外观吗?因为对我来说总是在顶部状态栏下,而且我有移动谷歌地图按钮的问题 您可以为您的谷歌地图添加填充。使用这个,mMap.setPadding(10, 20, 10, 10);这就是您避免地图组件位于栏下方的方法。 @Peter 也检查了接受的答案,在您的活动中使用这些标志将起到在状态栏下绘图的作用,甚至稍后更改状态栏的颜色。 我使用了来自 Android studio 'Navigation dreawer activity' 的默认示例项目。我有'android.support.v4.widget.DrawerLayout'和谷歌地图的'片段'。我无法向片段添加填充。有什么建议吗? :-) @Peter 看看这个.. developers.google.com/maps/documentation/android-api/…【参考方案4】:

在任何活动中实现这一目标

    添加样式:
 <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
                <item name="colorPrimary">@color/colorPrimary</item>
                <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
                <item name="colorAccent">@color/colorAccent</item>
                <item name="android:statusBarColor">@android:color/transparent</item>
                <item name="android:windowBackground">@android:color/white</item>
            </style>

    在 XML 中使用 CoordinatorLayout 作为根布局

    在 oncreate() 方法中,在 setcontentview 使用之前

    window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE 或 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

【讨论】:

我只希望状态栏透明,但导航应该是默认的。在我的情况下,沉浸式模式全屏和透明导航覆盖【参考方案5】:

对于最新的 android 版本 R 和向后兼容性,这对我有用。

WindowCompat.getInsetsController(window, window.decorView)?.isAppearanceLightStatusBars =false /* true for dark icon on StatusBar and false for white icon on StatusBar */
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, window.decorView)?.show(WindowInsetsCompat.Type.statusBars())
ViewCompat.setOnApplyWindowInsetsListener(findViewById(android.R.id.content))  rootView, insets ->
    val navigationBarHeight = insets.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom
    rootView.setPadding(0, 0, 0, navigationBarHeight)
    insets

Fragment 可以使用activity?.window...

【讨论】:

以上是关于透明状态栏不适用于 windowTranslucentNavigation="false"的主要内容,如果未能解决你的问题,请参考以下文章

Cordova Android状态栏设置为透明

text windowSoftInputMode =“adjustResize”不适用于半透明动作/导航栏

带有透明状态栏的全屏片段(以编程方式)

iOS 8:状态栏不适用于 UIImagePickerController

创建新的状态栏不适用于 targetSdkVersion 30

状态栏不适用于错误的 headerShown