NestedScrollView и CoordinatorLayout. Проблема с прокруткой

У меня странная проблема с CoordinatorLayout и NestedScrollView (с библиотекой поддержки дизайна 22.2.0)

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

Вот небольшой пример:введите здесь описание изображения

Вот код:

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

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

        <FrameLayout
            android:paddingTop="24dp"
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="@dimen/padding">

        </FrameLayout>

    </android.support.v4.widget.NestedScrollView>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab_action"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="end|bottom"
        android:layout_margin="16dp"
        android:visibility="gone"
        android:src="@drawable/ic_done" />

</android.support.design.widget.CoordinatorLayout>

comment
вот лучшее решение, проверьте это.   -  person Mansukh Ahir    schedule 22.01.2016


Ответы (5)


Это также можно наблюдать в демоверсии cheesesquare при удалении всех карт, кроме одной, во фрагменте сведений.

Я смог решить это (на данный момент), используя этот класс: https://gist.github.com/EmmanuelVinas/c598292f43713c75d18e

<android.support.v4.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="com.evs.demo.layout.FixedScrollingViewBehavior">
    .....   
</android.support.v4.widget.NestedScrollView>
person Paul Burke    schedule 12.06.2015
comment
В настоящее время обходной путь является хорошим решением. Я думаю, что это определенно ошибка в библиотеке поддержки. - person Gabriele Mariotti; 12.06.2015
comment
Хорошее исправление. Однако, когда содержимое прокрутки меньше, чем сама прокрутка, прокрутка по-прежнему реагирует и сворачивает панель инструментов. Любая идея, как просто отключить прокрутку и свернуть, когда прокрутка вообще не нужна (для сценариев с небольшим контентом) - person GuillermoMP; 13.06.2015
comment
@GuillermoMP Вам удалось это исправить? Я столкнулся с той же проблемой. - person Jerry; 09.07.2015
comment
Это исправление отлично работает после onMeasure. Но после запуска фрагмента ViewCompat.isLaidOut(appBar) всегда ложно. И этот метод возвращает true после, например, поворота экрана. Где я не прав? - person VKDev; 27.10.2015
comment
Вот пример приложения, демонстрирующего NestedScrollView в родительском ScrollView: github.com/AdamSHurwitz/NestedScrolling - person Adam Hurwitz; 21.06.2016
comment
app:layout_behavior= не позволяет мне вводить имя класса. как вы входите в этот класс? - person chari sharma; 14.09.2018

Я думаю, что это не ошибка в библиотеке поддержки, просто используйте это

<android.support.v4.widget.NestedScrollView
    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:fillViewport="true"
    android:layout_gravity="fill_vertical"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">
person LiFei    schedule 21.07.2015
comment
Я пробовал обходиться выше и работает как шарм. Попробуй это! - person datienza; 06.08.2015
comment
На самом деле, это работает! По крайней мере на 22.2.1. Хотя для меня не было необходимости иметь fillViewPort. - person Pin; 06.08.2015
comment
Я просто добавил «android: layout_gravity = fill_vertical», и это сработало. Спасибо @LiFei. - person Suresh Kumar; 11.08.2015
comment
Это правильный ответ на вопрос. Это не ошибка в NestedScrollView, и класс, использованный выше, не нужен. - person Y.S; 31.08.2015
comment
Это определенно не работает в моей ситуации, когда внутри вложенного прокрутки у меня есть фрагмент с внутренним просмотром повторного использования. Если я использую этот метод, recyclerview прокручивается, но панель приложений больше не рушится. - person Neal Sanche; 29.09.2015
comment
Мне нужен fillViewport... не уверен, почему. - person kenyee; 18.01.2017

android:layout_gravity="fill_vertical" у меня тоже сработало.

person Ugo    schedule 12.11.2015

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

...
compileSdkVersion 23
...
targetSdkVersion 23
...
compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:support-v4:23.1.0'
compile 'com.android.support:design:23.1.0'
person Aleks Nine    schedule 25.10.2015
comment
для интереса, переключение на v23 библиотеки поддержки сломало мои сборки с помощью sdk, заявив, что я не использую Theme.AppCompat, хотя я использую. - person Richard Le Mesurier; 10.11.2015
comment
Ну, у меня также была проблема с v23 с устаревшими библиотеками Apache, но это проблема для другого вопроса. Как только вы решите это, попробуйте посмотреть, исправлено ли это. - person Aleks Nine; 10.11.2015

Метод onMeasureChild() вызывается много раз в процессе компоновки. По-видимому, ключ к получению ненулевого значения высоты дочернего элемента в начале процесса. ScrollingViewBehavior не может сделать это в следующем:

int scrollRange = appBar.getTotalScrollRange();
int height = parent.getHeight() 
             - appBar.getMeasuredHeight()
             + scrollRange;

FixedScrollingviewBehavior исправляет это с помощью:

int height = parent.getHeight() 
             - appBar.getMeasuredHeight() 
             + Math.min(scrollRange, parent.getHeight() - heightUsed);

что очень рано дает высоте значение -128, высоту панели приложения.

Альтернативой, близкой к оригиналу, является:

int height = parent.getMeasuredHeight()
             - appBar.getMeasuredHeight()
             + scrollRange;
person Jon    schedule 01.07.2015
comment
Не могли бы вы объяснить? Мне, как новичку, трудно следовать. Я попытался прочитать класс ScrollingViewBehavior и его базовый класс HeaderScrollingViewBehavior. Но я не могу понять это - person Kathir; 25.12.2018