NestedScrollView and CoordinatorLayout. Issue on Scrolling

63,761

Solution 1

This can also be observed in the cheesesquare demo when removing all but one card in the details fragment.

I was able to solve this (for now) using this class: 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>

Solution 2

I think that it is not a bug in the support lib,just use this

<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">

Solution 3

android:layout_gravity="fill_vertical" worked for me too.

Solution 4

I might be late with my answer but here goes. I was having a similar problem, but none of the above mentioned solutions worked for me. In the end I fixed it by using version 23 of the support library.

...
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'

Solution 5

The onMeasureChild() method is called many times during the layout process. Apparently, the key is getting a non-zero value for the child height early in the process. ScrollingViewBehavior fails to do so in the following:

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

FixedScrollingviewBehavior fixes this with:

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

which very early gives height the value of -128, the height of the app bar.

An alternative, close to the original is:

int height = parent.getMeasuredHeight()
             - appBar.getMeasuredHeight()
             + scrollRange;
Share:
63,761
Gabriele Mariotti
Author by

Gabriele Mariotti

An experienced professional with more than 20 years of work in IT scope, with deep focus on develop and technical areas. Strong leadership with a proven ability to design software solutions and to manage teams. You can follow me on: Linkedin Twitter Github

Updated on July 09, 2022

Comments

  • Gabriele Mariotti
    Gabriele Mariotti almost 2 years

    I have a strange issue with the CoordinatorLayout and the NestedScrollView (with the design support library 22.2.0)

    Using a content smaller than NestedScrollView I should have a fixed content. However trying to scroll up and down the content I can obtain that the content is displaced and never again in their own place.

    Here a little sample:enter image description here

    Here the code:

    <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>
    
  • Gabriele Mariotti
    Gabriele Mariotti almost 9 years
    Currently the workaround is a good solution. I think that it is definitely a bug in the support lib.
  • GuillermoMP
    GuillermoMP almost 9 years
    Nice fix. However, when the scroll content is smaller than the scroll itself, the scroll still responds and collapses the toolbar. Any idea how to just disable the scroll and the collapse when the scroll is not needed at all (for small content scenarios)
  • Jerry
    Jerry almost 9 years
    @GuillermoMP Did you manage to fix this? I'm facing the same issue.
  • datienza
    datienza over 8 years
    I've tried the work around above and works like a charm. Try it!
  • Pin
    Pin over 8 years
    Actually, this does work! At least on 22.2.1. For me it wasn't necessary to have fillViewPort though.
  • Suresh Kumar
    Suresh Kumar over 8 years
    I just added 'android:layout_gravity="fill_vertical"' and it worked. Thanks @LiFei.
  • Yash Sampat
    Yash Sampat over 8 years
    This is the correct answer to the question. It isn't a bug in the NestedScrollView, and the class used above is unnecessary.
  • Neal Sanche
    Neal Sanche over 8 years
    This definitely doesn't work in my situation, where inside the nested scrollview I have a fragment with an internal recyclerview. If I use this method, the recyclerview scrolls, but the appbar no longer collapses.
  • VKDev
    VKDev over 8 years
    This fix works fine after onMeasure. But after starting of the fragment ViewCompat.isLaidOut(appBar) is always false. And this method returns true after, for example, screen-rotation. Where I'm wrong?
  • Richard Le Mesurier
    Richard Le Mesurier over 8 years
    for interest, switching to v23 of support lib broke my builds with sdk claiming I was not using an Theme.AppCompat even though I am.
  • Aleks Nine
    Aleks Nine over 8 years
    Well I also had a problem with v23 with Apache's deprecated libraries, but that's a problem for another question. Once you've solved that try to see if this is fixed.
  • AdamHurwitz
    AdamHurwitz almost 8 years
    Here's a sample App demonstrating a NestedScrollView within a parent ScrollView: github.com/AdamSHurwitz/NestedScrolling
  • kenyee
    kenyee over 7 years
    I needed the fillViewport...not sure why.
  • chari sharma
    chari sharma over 5 years
    app:layout_behavior= is not let me to enter the class name. how you enter this class?
  • Kathir
    Kathir over 5 years
    Could you please explain? Being a beginner, I find it difficult to follow. I tried reading the ScrollingViewBehavior class and it's base class HeaderScrollingViewBehavior. But I am unable to make sense of it