Search code examples
androidandroid-support-libraryandroid-design-libraryandroid-appbarlayout

AppBarLayout child doesn't collapse when scrolling


I have a AppBarLayout which contains an horizontal RecyclerView among its children. The sibling of the AppBarLayout is a ViewPager (which contains a vertical RecyclerView).

Here is the XML:

<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinatorLayout"
    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"
    tools:context=".ui.search.SearchResultFragment">

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

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

    <LinearLayout
        android:id="@+id/header_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:background="@color/white"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <ImageView
            android:id="@+id/back_image_view"
            android:layout_width="?attr/actionBarSize"
            android:layout_height="?attr/actionBarSize"
            android:scaleType="center"
            android:src="@drawable/ic_backarrow_gray"/>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/query_terms_recycler_view"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_gravity="center_vertical"
            android:layout_weight="1"/>

        <ImageView
            android:id="@+id/search_image_view"
            android:layout_width="?attr/actionBarSize"
            android:layout_height="?attr/actionBarSize"
            android:scaleType="center"
            android:src="@drawable/ic_search_gray"/>

    </LinearLayout>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/related_terms_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/search_term_bg"
        app:layout_scrollFlags="scroll|enterAlways"/>

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/d8"
        android:background="@color/tab_and_nav_bar"/>

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

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

I already have another UI with AppBarLayout which is able to respond to scroll successfully with a Toolbar . The code is pretty much the same, but in this case something is wrong because the RecyclerView is not collapsing / hiding.


Solution

  • Big thanks to @m vai for the tips

    I solved this problem customising the behaviour of the AppBarLayout Here is the code:

    private void setAppBarLayoutBehaviour() {
        AppBarLayout.Behavior behavior = new AppBarLayout.Behavior() {
    
            @Override
            public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
                // Trigger the following events if it is a vertical scrolling
                return nestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL || super.onStartNestedScroll(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
            }
    
            @Override
            public void onNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
                super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
    
                // If I slowly reach the top, without fling, show the RecyclerView
                int[] firstVisiblePositions = ((StaggeredGridLayoutManager) ((RecyclerView) target).getLayoutManager()).findFirstCompletelyVisibleItemPositions(null);
                for (int position : firstVisiblePositions) {
                    if (position == 0) {
                        showRelatedTerms();
                        break;
                    }
                }
            }
    
            @Override
            public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) {
                if (velocityY > 500) {
                    // Hide the RecyclerView
                } else if (velocityY < -500) {
                    // Show the recyclerView
                }
                return true;
            }
        };
        ((CoordinatorLayout.LayoutParams) appBarLayout.getLayoutParams()).setBehavior(behavior);
    }
    

    And I didn't apply any scrollFlags in the XML.