ViewPager2 имеет неправильный размер при использовании с AppBarLayout и сворачивающейся панелью инструментов

У меня есть этот макет:

<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
   android:layout_height="match_parent"
   android:fitsSystemWindows="true"
   tools:context=".MainActivity">

<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/OfferingsMaterialTheme.AppBarOverlay"
    android:fitsSystemWindows="true">

    <androidx.appcompat.widget.Toolbar
      android:id="@+id/toolbar"
      app:layout_scrollFlags="scroll|enterAlways"
      android:layout_width="match_parent"
      android:layout_height="?android:attr/actionBarSize"
      android:background="?android:attr/colorPrimary"
      app:titleTextColor="@color/icons"
      app:title="@string/offeringsfragment_title"
      app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

    <com.google.android.material.tabs.TabLayout
        android:id="@+id/tabs"
        style="@style/Widget.MaterialComponents.TabLayout.Colored"
        app:tabMaxWidth="0dp"
        app:tabGravity="fill"
        app:tabMode="fixed"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
</com.google.android.material.appbar.AppBarLayout>

<androidx.viewpager2.widget.ViewPager2
    android:id="@+id/viewpager"
    app:layout_anchorGravity="bottom"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Я использую app:layout_scrollFlags="scroll|enterAlways" в своей панели инструментов, поэтому она сворачивается, когда пользователь прокручивает вверх (внутри ViewPager2 есть RecyclerView). Проблема в том, что нижняя часть представления в ViewPager2 не видна. Кажется, высота рассчитывается неправильно. См. это:

введите здесь описание изображения

В красной части вы можете видеть, что ViewPager2 расширяется по размеру экрана. Я прочитал много сообщений об этом, но не смог найти решение для ViewPager2. Среди прочего, я пытался обернуть его внутри LinearLayout, но тогда панель инструментов больше не рушится. Любые идеи?


comment
Как вы определяете высоту RecyclerView, это match_parent я думаю, это будет проблемой, если его wrap_content   -  person Sally    schedule 17.07.2020
comment
Это match_parent   -  person to_sam    schedule 17.07.2020


Ответы (1)


Для тех, у кого такая же проблема: ViewPager2, кажется, имеет ошибку в вычислении правильной высоты. Единственное решение, которое сработало для меня, это это. Здесь мы делаем это:

Решение, которое я нашел для этой проблемы, состоит из 2 частей.

  1. Добавьте отступ, равный высоте AppBarLayout, в НИЖНЮЮ часть NestedScrollView. В моем случае, поскольку AppBarLayout содержал только Toolbar, высота была ?attr/actionBarSize.
    android:paddingBottom="?attr/actionBarSize"

  2. Добавление пользовательского AppBarLayout.OnOffsetChangedListener к AppBarLayout, который изменяет высоту NestedScrollView при сворачивании панели инструментов.

     class ScrollingOffsetFixListener(
         private val nestedScrollView: NestedScrollView
     ): AppBarLayout.OnOffsetChangedListener {
    
     private var originalHeight = 0
     private var firstOffset = true
    
     override fun onOffsetChanged(layout: AppBarLayout?, offset: Int) {
         if(firstOffset) {
             firstOffset = false
             originalHeight = nestedScrollView.measuredHeight
         }
    
         val params = nestedScrollView.layoutParams
         params.height = originalHeight + (offset * -1)
    
         nestedScrollView.layoutParams = params
        }
     }
    
person to_sam    schedule 18.07.2020
comment
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными, если связанная страница изменится. – Из обзора - person David Maze; 18.07.2020