ViewPager в CoordinatorLayout неожиданно сжимается

В моем Android-приложении, работающем на Android 5.1.1, у меня есть макет с помощью Toolbar с TabLayout , а под ним – ViewPager . Все они объединены в CoordinatorLayout .

На первой странице ViewPager используется элемент CardView обслуживающий элементы CardView .

Моя проблема заключается в том, что мой ViewPager продолжает ViewPager таким образом, чтобы мои CardView списка CardView обрезались.

Моя основная компоновка выглядит в основном так:

 <android.support.design.widget.CoordinatorLayout android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.design.widget.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent" > <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager app:layout_behavior="@string/appbar_scrolling_view_behavior" android:layout_width="match_parent" android:layout_height="match_parent"/> </android.support.design.widget.CoordinatorLayout> 

И первый фрагмент, обслуживаемый моим ViewPager выглядит так:

 <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <android.support.v7.widget.RecyclerView android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dp"/> </FrameLayout> 

Это делает что-то похожее на это:

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

При нажатии кнопки в моем макете я использую startActivityForResult для вызова другого действия, а иногда при возврате к моей работе мой список обрезается, так что startActivityForResult только половина первого элемента:

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

После поворота по горизонтали на другой пейджер в ViewPager а затем обратно, проблема исчезает, поэтому кажется, что повторная компоновка не была правильно запущена. Нажатие HOME и возобновление моей активности НЕ разрешают проблему. Обратите внимание, что это происходит, даже если я не изменяю свой макет каким-либо образом, я просто возвращаюсь из вызова startActivityForResult. И да, это случается только иногда … И у меня нет фоновых потоков, которые могли бы объяснить кажущееся случайное поведение.

Сначала я подумал, что сокращение RecyclerView сократилось, но с помощью HierarchyViewer я смог найти, что на самом деле весь ViewPager уменьшился примерно до половины его первоначальной высоты.

Я попробовал различные хаки, чтобы обойти это, включая вызов invalidate() и requestLayout() для всего моего просмотра hiearchy, но ничего не помогло (хотя переключение на другую страницу и исправление снова исправлено). Кроме того, это не те решения, к которым я хочу прибегнуть … Затем я попытался изменить высоту wrap_content на wrap_content , что фактически решило эту конкретную проблему; После возвращения в мою работу первый элемент в моем RecyclerView никогда не обрезается, и я могу прокручивать вниз до других элементов. Однако теперь вместо этого последний элемент моего списка всегда обрезается, как видно на этом скриншоте, где список прокручивается до конца:

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

Поскольку я сейчас нахожусь в точке, где я действительно не понимаю, что происходит, мне нужна помощь. Что я должен использовать как layout_height для моего ViewPager и, прежде всего, почему? Для меня match_parent имеет смысл, но как я должен здесь думать? Существует ли разумная причина, по которой мои взгляды обрезаны при использовании match_parent , или я действительно сталкивался с ошибкой в ViewPager , RecyclerView и / или CoordinatorLayout ? Как я могу убедиться, что мой ViewPager последовательно заполняет всю область экрана под AppBar и что мой RecyclerView можно прокручивать по вертикали, чтобы правильно отображать все CardView списка CardView ?

Solutions Collecting From Web of "ViewPager в CoordinatorLayout неожиданно сжимается"

У меня возникла аналогичная проблема при использовании старой версии библиотеки поддержки.

См. Следующие вопросы:

https://code.google.com/p/android/issues/detail?id=176406 https://code.google.com/p/android/issues/detail?id=176187

Убедитесь, что вы используете последнюю версию Support library , версия 23.1 на момент написания этой статьи.

Оказывается, это почти наверняка ошибка в CoordinatorLayout или, что еще более вероятно, в AppBarLayout$ScrollingViewBehavior . Стремясь создать MCVE, я понял, что мой суб-активность имел IME на экране, что вызвало сокращение ViewPager – когда моя активность возобновляется после onActivityResult , ViewPager сокращается из-за уменьшения экрана реального – вывести из IME, но он никогда не расширяется, несмотря на то, что IME больше не отображается и тот факт, что CoordinatorLayout действительно расширен.

После отладки и onLayout через onLayout и onMeasure CoordinatorLayout и ViewPager теперь я уверен, что CoordinatorLayout неправильно ViewPager изменение размера своим onLayout onMeasure .

Я обнаружил, что могу «исправить» проблему, вызвав requestLayout на моем ViewPager , но только если вызов достаточно задерживается (10 мс никогда не работает, 100 мсек работает большую часть времени):

 protected void onActivityResult(int requestCode, int resultCode, Intent data) { mHandler.postDelayed(new Runnable() { @Override public void run() { mViewPager.requestLayout(); } }, 100); } 

Это, очевидно, не является надежным решением, но, выяснив, что еще больше выясняется, мне, вероятно, даже не нужен CoordinatorLayout так как у меня нет никакого продвинутого поведения прокрутки. Поэтому моим решением будет просто перейти с LinearLayout или RelativeLayout качестве моей корневой группы. Приятно и просто, не нужно усложнять ситуацию.

 <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <android.support.design.widget.AppBarLayout android:layout_height="wrap_content" android:layout_width="match_parent" > <android.support.v7.widget.Toolbar android:layout_width="match_parent" android:layout_height="wrap_content" /> <android.support.design.widget.TabLayout android:layout_width="match_parent" android:layout_height="wrap_content" /> </android.support.design.widget.AppBarLayout> <android.support.v4.view.ViewPager android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout> 

Однако я попытаюсь сконденсировать это на простом примере и сообщить об ошибке в Google.

Что касается того, что я должен использовать в качестве высоты для моего ViewPager , мое первоначальное использование match_parent все же кажется разумным. Тот факт, что wrap_content решил проблему (но вызвал другие проблемы), вероятно, объясняется только несоответствиями, вызванными ошибкой.

В вашем фрагменте просто удалите frameLayout и сделайте родительский ресурс recyclerView … Надеюсь, он будет работать:

  <android.support.v7.widget.RecyclerView android:scrollbars="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="8dp"> <android.support.v7.widget.RecyclerView/>