Как применить вставки к CollapsingToolbarLayout с изображением внутри, чтобы изображение на панели инструментов отображалось за строкой состояния? - PullRequest
2 голосов
/ 06 ноября 2019

Я пытаюсь настроить полноэкранный режим для Android 10 с помощью вставок. Я хотел, чтобы изображение на панели инструментов было нарисовано за строкой состояния. Я пытался использовать флаг android:fitsSystemWindows в различных комбинациях, но он не работает, AppBarLayout не имеет правильного заполнения, и строка состояния слегка перекрывает элементы управления панели инструментов. Поэтому я использовал удобную WindowInsetsCompat оболочку, библиотеку Insetter от Chris Banes , чтобы установить отступы в соответствии с вставками окна системы.

Вот мой макет:

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"

  android:id="@+id/book_activity_root"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:animateLayoutChanges="true"
  tools:context="com.bookcrossing.mobile.ui.bookpreview.BookActivity"
  >

  <androidx.core.widget.NestedScrollView
    android:id="@+id/nestedScrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    >
    ...
  </androidx.core.widget.NestedScrollView>
  <com.google.android.material.appbar.AppBarLayout
    android:id="@+id/toolbarContainer"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    >
    <com.google.android.material.appbar.CollapsingToolbarLayout
      android:id="@+id/collapsingToolbarContainer"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      app:contentScrim="?attr/colorPrimary"
      app:expandedTitleGravity="bottom"
      app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
      app:titleEnabled="true"
      app:toolbarId="@id/toolbar"
      >

      <ImageView
        android:id="@+id/cover"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:contentDescription="@string/cover_description"
        android:scaleType="centerCrop"
        android:cropToPadding="true"
        app:layout_collapseMode="parallax"
        app:layout_collapseParallaxMultiplier="0.5"
        />

      <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:layout_collapseMode="pin"
        app:layout_scrollFlags="scroll|enterAlways"
        tools:title="War and Peace"
        />

    </com.google.android.material.appbar.CollapsingToolbarLayout>
  </com.google.android.material.appbar.AppBarLayout>
  <com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/favorite"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/default_padding"
    android:clickable="true"
    android:focusable="true"
    android:src="@drawable/ic_turned_in_not_white_24dp"
    app:layout_anchor="@id/toolbar_container"
    app:layout_anchorGravity="bottom|right|end"
    />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Вот как я устанавливаю отступы в коде:

    Insetter.setOnApplyInsetsListener(toolbarContainer, (view, windowInsets, initial) -> {
      view.setPadding(initial.getPaddings().getLeft(),
        windowInsets.getSystemWindowInsetTop() + initial.getPaddings().getTop(),
        initial.getPaddings().getRight(), initial.getPaddings().getBottom());
    });

    Insetter.setOnApplyInsetsListener(cover, (view, windowInsets, initial) -> {
      ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
      params.topMargin = windowInsets.getSystemWindowInsetTop() + initial.getMargins().getTop();
      view.setLayoutParams(params);
    });

    Insetter.setOnApplyInsetsListener(nestedScrollView, (view, windowInsets, initial) -> {
      view.setPadding(initial.getPaddings().getLeft(), initial.getPaddings().getTop(),
        initial.getPaddings().getRight(),
        windowInsets.getSystemWindowInsetBottom() + initial.getPaddings().getBottom());
    });

    Insetter.setOnApplyInsetsListener(favorite, (view, windowInsets, initialPadding) -> {
      view.setPadding(initialPadding.getPaddings().getLeft(), initialPadding.getPaddings().getTop(),
        windowInsets.getSystemWindowInsetRight() + initialPadding.getPaddings().getRight(),
        initialPadding.getPaddings().getBottom());
    });

Я устанавливаю флажки окна для полноэкранного режима:

root.setSystemUiVisibility(
      View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

И вот такой результат:

Example of the incorrect padding

Строка состояния установлена ​​прозрачной, синий цвет - из панели инструментов с верхним отступом.

В качестве окончательного результата мне бы хотелосьМожно ли вообще нарисовать изображение за строкой состояния?

Я тестирую на эмуляторе Android 10.

1 Ответ

0 голосов
/ 06 ноября 2019

Как я помню, вам не нужно поддерживать отступы в CoordinatorLayout вручную, см. Функцию setupForInsets в классе CoordinatorLayout. Для поддержки рисования за строкой состояния вы должны установить android:fitsSystemWindows="true" для CoordinatorLayout:

<androidx.coordinatorlayout.widget.CoordinatorLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"    
  android:id="@+id/book_activity_root"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:animateLayoutChanges="true"
  tools:context="com.bookcrossing.mobile.ui.bookpreview.BookActivity"
  >

И, как я понимаю, вам не нужно animateLayoutChanges здесь. Он отвечает за анимацию изменений макета, таких как удаление / добавление и отображение / скрытие видов.

...