Меняйте вставки для сворачивающейся панели инструментов в зависимости от ее состояния

У меня есть сворачивающаяся панель инструментов и некоторый макет, который я хочу свернуть. Чтобы представление не уходило под строку состояния, я использую системные вставки, чтобы установить поле для сворачивающейся панели инструментов. Я извлек AppBarLayout в отдельный файл и включил его в CoordinatorLayout:

<com.google.android.material.appbar.AppBarLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/action_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/app_white"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?actionBarSize"
            android:background="@color/colorToolbar"
            android:elevation="4dp"
            android:focusable="true"
            android:focusableInTouchMode="true"
            app:contentInsetStartWithNavigation="0dp"
            app:layout_collapseMode="pin">

            ...
        </androidx.appcompat.widget.Toolbar>

        <com.google.android.material.card.MaterialCardView
            android:id="@+id/bonuses_widget"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:cardCornerRadius="14dp"
            app:cardElevation="3dp"
            app:layout_collapseMode="parallax">

            ...
        </com.google.android.material.card.MaterialCardView>
    </com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>

Поля для MaterialCardView устанавливаются из кода, потому что макет не поддерживает добавление. Я добавляю поля для сворачивания панели инструментов с помощью вставок:

ViewCompat.setOnApplyWindowInsetsListener(action_bar) { _, insets ->
    collapsing_toolbar.setMarginTop(insets.systemWindowInsetTop)
    insets
}

Это хорошо работает, когда сворачивающаяся панель инструментов развернута, но в свернутом состоянии панель инструментов находится под строкой состояния:

Я прочитал этот вопрос, реализовал AppBarStateChangeListener и использую его следующим образом:

action_bar.addOnOffsetChangedListener(object : AppBarStateChangeListener() {
    override fun onStateChanged(appBarLayout: AppBarLayout, state: State) {
        if (state == State.COLLAPSED) {
            ViewCompat.setOnApplyWindowInsetsListener(collapsing_toolbar) { _, insets ->
                toolbar.setMarginTop(insets.systemWindowInsetTop)
                insets
            }
        }
        if (state == State.EXPANDED) {
            ViewCompat.setOnApplyWindowInsetsListener(collapsing_toolbar) { _, insets ->
                toolbar.setMarginTop(0)
                insets
            }
        }
    }
})

Это не помогло, насколько я понимаю до сих пор, вставки строки состояния уже обрабатываются панелью действий, а сворачивающейся панели инструментов нечего обрабатывать. работало, но привело к другой проблеме:

В конце концов, я попытался удалить вставки и просто установил android:fitsSystemWindows="true" на панель действий, это устраняет проблему с панелью инструментов под строкой состояния, но строка состояния неожиданно приобретает странный цвет (фиолетовый), который не представлен в цветах приложения.
Надеюсь, кто-то знает жарко правильно обращаться со вставками в этом случае.


person QuarK    schedule 18.06.2021    source источник
comment
Вы придали какой-либо цвет своей строке состояния? А на какой ОС вы тестируете?   -  person Muhammad Zahab Ahmad Khan    schedule 18.06.2021
comment
Это может помочь.   -  person Muhammad Zahab Ahmad Khan    schedule 18.06.2021
comment
@MuhammadZahabAhmadKhan Я не задал никакого определенного цвета строке состояния в этом фрагменте, он имеет цвет, определенный приложением. Тестирую на Android 8.   -  person QuarK    schedule 18.06.2021
comment
Мой вопрос в основном касается вставок, цвет строки состояния должен устанавливаться системой с использованием цветов приложения.   -  person QuarK    schedule 18.06.2021
comment
Вы звонили setSupportActionBar()?   -  person Sam Chen    schedule 18.06.2021
comment
@SamChen Моя панель инструментов фрагментирована, поэтому я этого не делал.   -  person QuarK    schedule 21.06.2021


Ответы (2)


Вы можете попробовать вызвать setSupportActionBar() в своем Fragment, потому что это работает для меня:

(requireActivity() as AppCompatActivity).apply {
    //supportActionBar?.hide()    //may need this to hide the Activity actionBar

    setSupportActionBar(binding.toolbar)
}

setHasOptionsMenu(true)    //don't forget this

Демо: https://youtu.be/kmnsep_V-jE

person Sam Chen    schedule 21.06.2021
comment
Я пробовал это решение, к сожалению, это не помогло - person QuarK; 02.07.2021

В конце концов я нашел подходящее решение:

ViewCompat.setOnApplyWindowInsetsListener(action_bar) { view, insets ->
    view.updatePadding(top = insets.systemWindowInsetTop)
    insets
}

Осталась проблема с белым фоном под строкой состояния (мне нужно, чтобы он был темным, как на скриншотах слева), но первоначальная проблема решена.

person QuarK    schedule 02.07.2021