Прозрачная строка состояния не работает с windowTranslucentNavigation="false"

Я разрабатываю 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>

Это делает приложение похожим на это

андроид: windowTranslucentNavigation =

Если я удалю android:windowTranslucentNavigation стиль или установите его false в Fullscreen, это исправляет проблему с панелью навигации. Проблема в том, что строка состояния становится полностью белой вместо того, чтобы оставаться прозрачной и отображать содержимое позади нее.

андроид: windowTranslucentNavigation =

Я пытался использовать fitsSystemWindow="true" в моих макетах, но это не решило проблему. Кто-нибудь знает, почему это происходит?

5 ответов

Решение

android:windowTranslucentNavigation делает одну вещь, которая android:statusBarColor не делает, что запрашивает SYSTEM_UI_FLAG_LAYOUT_STABLE а также SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN флаги.

Это те, которые вам нужно запросить, чтобы нарисовать за строкой состояния.

Запросите их в onCreate вашей Activity:

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

В качестве альтернативы вы также можете просто установить фон темы вашего приложения, и это также будет появляться за строкой состояния.

Больше информации здесь.

Насколько я знаю, нет правильного способа установить цвет строки состояния на API ниже 19.

Для API 19+ вы можете использовать аналогичный атрибут для windowTranslucentNavigation только для строки состояния:

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

Заметки:

  • Причина, по которой вы получили белую строку состояния, заключается в том, что

    <item name="android:statusBarColor">@color/transparent</item> 
    
  • Есть некоторые хаки, которые работают на устройствах конкретного производителя, но я бы не стал их использовать сам.

Я борюсь с этим более 3 часов. Оберните все в CoordinatorLayout, это единственный, который, кажется, обращает внимание на fitsSystemWindow = "true" или "false"

Это мой основной фрагмент деятельности

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

    <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_width="match_parent"
    android:layout_height="match_parent"
    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_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/transparent"
        android:theme="@style/ToolbarTheme"
        app:popupTheme="@style/AppTheme.PopupOverlay">

        <android.support.v7.widget.AppCompatImageView
            android:layout_width="wrap_content"
            android:layout_height="?actionBarSize"
            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 отображаться под строкой состояния.

У меня есть панель действий, куда идет логотип компании.

И другие кнопки пользовательского интерфейса "layout_action_buttons" также обернуты в компоновку Coordinator, так что работает fitsSystemsWindows.

Проверьте это.

Чтобы добиться этого в любой деятельности

  1. Добавьте стиль:
 <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>
  1. Использовать CoordinatorLayout в качестве корневого макета в XML

  2. В методе oncreate() перед использованием setcontentview

    window.decorView.systemUiVisibility = Просмотр.SYSTEM_UI_FLAG_LAYOUT_STABLE или Просмотр.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

Для последней версии 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
}

Для фрагмента вы можете использовать activity?.window...

Другие вопросы по тегам