AppBarLayout child doesn't collapse when scrolling

冷暖自知 提交于 2019-12-03 21:11:52
  • AppBarLayout is just a vertical LinearLayout, so order counts;
  • what makes child react to scroll gestures is actually defining the scroll flags through the android:layout_scrollFlags attribute.

From the official documentation for that flag, we can read that

The view will be scroll in direct relation to scroll events. This flag needs to be set for any of the other flags to take effect. If any sibling views before this one do not have this flag, then this value has no effect.

That means that your flag is ignored because the other childs do not have any flags. I believe the reason behind this is that we want only the top views to be hidden - bottom views can't disappear if there's still something above.

So the solution in this case (which you might not like) is to, either:

  • move that view to the top, so it will be the only view exiting;
  • give all views the scroll flag. They'll react together to scroll gestures, which might not be what you want.

    <AppBarLayout>
        <RecyclerView ...
            android:layout_scrollFlags="scroll|enterAlways"/>
    
        <LinearLayout ... >
        <TabLayout ... >
    </AppBarLayout>
    

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!