2

I have a ViewPager with Fragments which containe a RecyclerViews. A CollapsingTollbarLayout is above the ViewPager. Everythings works fine except during a programmatically scroll on the RecyclerView. Then the AppBarLayout or CollapsingToolbarLayout doesn't responde.

Here is my base layout xml:

<?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:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">

<android.support.design.widget.AppBarLayout
    android:id="@+id/appBarLayout"
    android:layout_width="match_parent"
    android:layout_height="256dp"
    android:fitsSystemWindows="true"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    app:layout_behavior="de.wackernagel.playball.ui.FlingBehaviour">

    <android.support.design.widget.CollapsingToolbarLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        android:id="@+id/collapsingToolbarLayout"
        app:contentScrim="?attr/colorPrimary"
        app:titleEnabled="false"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <ImageView
            android:contentDescription="@null"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerCrop"
            android:src="@drawable/showdown"
            app:layout_collapseMode="parallax"/>

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="@dimen/doubleActionBarSize"
            android:minHeight="?attr/actionBarSize"
            android:gravity="top"
            app:titleMarginTop="14dp"
            app:layout_collapseMode="pin"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@android:color/transparent"
            android:layout_gravity="bottom"
            app:tabTextColor="#BEFFFFFF"
            app:tabSelectedTextColor="#FFFFFFFF"
            app:tabContentStart="@dimen/keyline_2"
            app:tabMode="scrollable" />

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

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

<android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

My goal is it to collapse the CollapsingToolbarLayout during a programmatically scroll like a normal touch scroll.

I do this by

Activity get Fragment at current viewpager position
    Fragment get LayoutManager from RecyclerView
         LayoutManager scrollToPosition x

The scrolling behavior works on RecyclerView but the CollapsingToolbarLayout doesn't responde.

EDIT

Here is the layout of my fragments:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<de.wackernagel.playball.views.EmptyAwareRecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="8dp" />

<TextView
    android:id="@android:id/empty"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"/>

Happo
  • 1,265
  • 2
  • 15
  • 34
  • I wrote a post on triggering the collapse when a scroll is detected, needed for dpad usage (which uses progammatic scroll) http://novoda.com/blog/fixing-hiding-appbarlayout-android-tv/ – ataulm Oct 15 '15 at 08:15
  • @ataulm thank you for the hint. It points me to the right direction. – Happo Oct 15 '15 at 09:17
  • @ataulm by the way your technic to detect a programmatically scroll ( !recyclerView.isInTouchMode() ) doesn't work. Maybe this works only for TV because of the missing touch screen. – Happo Oct 16 '15 at 06:38
  • No, it doesn't work for another reason :P `isInTouchMode` returns true if the last user interaction was via touch as opposed to keyboard, dpad, remote etc. – ataulm Oct 16 '15 at 10:34

3 Answers3

3

It is quite easy to solve this problem, it comes from the fact, that getNestedScrollingParentForType(type) in NestedScrollingChildHelper#dispatchNestedScroll returns null (support lib version = 27.0.2) for the non-touch scroll, so scrolling is not dispatched. Thus, one should do the following before scrolling programmatically:

if (!recyclerView.hasNestedScrollingParent(ViewCompat.TYPE_NON_TOUCH)) {
    recyclerView.startNestedScroll(View.SCROLL_AXIS_VERTICAL, ViewCompat.TYPE_NON_TOUCH);
}
nikis
  • 10,833
  • 2
  • 32
  • 45
0

I was having this same problem, the AppBarLayout wouldn't collapse when the NestedScrollView was programmatically scrolled to the bottom. This resulted in Android miscalculating the bottom of the NestedScrollView when the AppBarLayout was expanded. When it was collapsed, it would scroll to the bottom correctly, but when it was expanded, it would come short of scrolling to the bottom by an amount equal to the height of the AppBarLayout. I found a simple fix for this by setting setExpanded to false immediately before attempting to scroll.

//scroll to the end of NestedScrollView
AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout);
appBarLayout.setExpanded(false, true);
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));

...or if not using lambda expressions (i.e < Java 8)

//scroll to the end of NestedScrollView
AppBarLayout appBarLayout = findViewById(R.id.app_bar_layout);
appBarLayout.setExpanded(false, true);
scrollView.post(new Runnable() {
    @Override
    public void run() {
        scrollView.fullScroll(View.FOCUS_DOWN);     
    }
});
smitty1
  • 1,094
  • 1
  • 12
  • 27
-1

<android.support.v4.view.ViewPager
    android:id="@+id/htab_viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<android.support.design.widget.AppBarLayout
    android:id="@+id/htab_appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:fitsSystemWindows="true"
    app:layout_behavior="example.com.final.TabParallax.FlingBehavior"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/htab_collapse_toolbar"
        android:layout_width="match_parent"
        android:layout_height="360dp"
        android:fitsSystemWindows="true"
        app:contentScrim="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|exitUntilCollapsed">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:padding="0dp">

            <ImageView
                android:id="@+id/htab_header"
                android:layout_width="match_parent"
                android:layout_height="359dp"
                android:background="@drawable/channel"
                android:fitsSystemWindows="true"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax" />

        </FrameLayout>

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

    <android.support.design.widget.TabLayout
        android:id="@+id/htab_tabs"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorAccent1"
        android:fitsSystemWindows="true"
        android:gravity="bottom"
        app:tabGravity="center"
        app:tabIndicatorColor="@android:color/white"
        app:tabMode="scrollable"
        app:tabSelectedTextColor="@android:color/white"
        app:tabTextColor="@android:color/white"
        />
</android.support.design.widget.AppBarLayout>

Nima
  • 1,584
  • 4
  • 22
  • 31