Reputation: 3018
I have made a test application with a CollapsingToolbarLayout and a ViewPager. The ViewPager contains three Fragments, one of which is only a simple RecyclerView. My problem is that the CollapsingToolbarLayout (or rather the AppBarLayout) does not expand/contract when the RecyclerView is scrolled, except when the layout is not fully expanded, the RecyclerView is at the top and I scroll downwards. Then the CollapsingToolbarLayout is expanding as well.
Note: I have uploaded the test application here.
My current layout is as follows:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true" >
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="256dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true" >
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="@+id/mm_recipe_activity_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/cake"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="pin"/>
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="48dp"
app:tabMode="fixed"
app:tabIndicatorHeight="0dp"
/>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
There are two types of Fragments used in the ViewPager, one with a simple TextView with lots of text and one with the ViewPager. The Fragments are all wrapped in a NestedScrollView
to make the scrolling in the ViewPager play nice with the rest of the layout as suggested here and other places. Here are the two Fragment layouts, first the one with a simple TextView,
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/pink">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lorem"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
and then the one with the RecyclerView:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true" >
<android.support.v7.widget.RecyclerView
android:id="@+id/yellow_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/yellow" />
</android.support.v4.widget.NestedScrollView>
How can I make the AppBarLayout/CollapsingToolbarLayout react to scrolling in this RecyclerView?
Here are some screenshots to show what I mean:
Scrolling upwards from the initial position scrolls the RecyclerView itself, but not the AppBarLayout/CollapsingToolbarLayout. I want scrolling up/down at this point to collapse/expand them normally.
In the first image, the CollapsingToolbarLayout is collapsed and the RecyclerView is at the top. If I scroll the RecyclerView down at this point I start expanding the CollapsingToolbarLayout, as should be expected. If I stop half way through and scroll the RecyclerView up, however, I still end up scrolling the RecyclerView upwards, as shown in the third image.
Bonus Question: What is the gray View at the bottom in the third image above? I cannot see that I have added it anywhere. It is also visible at the bottom of the layouts that are just a plain TextView, so it is not because of the RecyclerView.
Upvotes: 3
Views: 2546
Reputation: 3119
The problem here is that you shouldn't "nest" a RecyclerView inside a NestedScrollView.
Why?
Because a RecyclerView implements by itself the 'NestedScrollingChild' and 'ScrollingView' interfaces. A NestedScrollView is used to support Views that don't have the Scrolling features, like the LinearLayout which you successfully implemented in the other cases.
Indeed the yellow_fragment.xml works as intended when changed to:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/yellow_recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/yellow"
android:fillViewport="true"
/>
Bonus Answer: adding android:fillViewport="true"
to your RecyclerView and your NestedScrollViews in green_fragment.xml and pink_fragment.xml will get rid of the grey strip at the bottom of your views. What's this sorcery you might ask:
When a child view inside a Scroll View is smaller than the screen, then android:fillViewport="true"
is the way to expand that view to fill your screen. Check its effect below:
android:fillViewport = "true" _ vs "false" _
I deleted a paragraph of your TextView's text to highlight the difference even more. Check out Romain Guy's blog post concerning this function for more info.
EDIT: as Krøllebølle mentioned in comments, make sure to have the latest support library version because it may be the reason for the gray stripe to persist even after adding android:fillViewport="true"
in your view.
Upvotes: 1
Reputation: 1731
Its default background color of parent layout. You will always see it until recyclerView/TextView/ViewPager doesn't cover the whole screen. You are having wrap_content as height to both the element. Try to make them match_parent and check the result.
Upvotes: 0