* 上也有人讨论这个问题,视频也是在这个问题下面看到的。
这段时间在项目用到 AppBarLayout 加 RecyclerView的时候,fling 下滑的时候,AppBarLayout总是不跟随RecycleView下滑,导致让人看起来非常的不顺畅,这个应该是是bug,听说26sdk 已经解决了,但是我升级 了 编译sdk到26 确实解决了,但是结合Viewpage下去又出现了奇葩的滑动冲突,找了很久都没找到MOVE事件到底是被谁消费了。因此自己处理下这个问题。
解决方法:重写
AppBarLayout.Behavior
判断滚动方向,以及RecycleView 滚动停止,后重新计算Y方向速度,通知AppBarLayout进行Fling滚动即可。
import android.content.Context; import android.support.design.widget.AppBarLayout; import android.support.design.widget.CoordinatorLayout; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.View; /** * Created by xff on 2018/3/13. */ public final class FlingBehavior extends AppBarLayout.Behavior { private boolean isPositive; AppBarLayoutScrollListem appBarLayoutScrollListem ; public FlingBehavior(Context context, AttributeSet attrs) { super(context, attrs); appBarLayoutScrollListem= new AppBarLayoutScrollListem(context); } @Override public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) { if (target instanceof RecyclerView) { RecyclerView recyclerView = (RecyclerView) target; recyclerView.removeOnScrollListener(appBarLayoutScrollListem); recyclerView.addOnScrollListener(appBarLayoutScrollListem); appBarLayoutScrollListem.coordinatorLayout = coordinatorLayout; appBarLayoutScrollListem.child = child; appBarLayoutScrollListem.target = target; appBarLayoutScrollListem.velocityX = velocityX; appBarLayoutScrollListem.velocityY = velocityY; appBarLayoutScrollListem.consumed = false; } return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY); } @Override public boolean onNestedFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { if (velocityY > 0 && !isPositive || velocityY < 0 && isPositive) { velocityY = velocityY * -1; } if (target instanceof RecyclerView && velocityY < 0) { appBarLayoutScrollListem.coordinatorLayout = coordinatorLayout; appBarLayoutScrollListem.child = child; appBarLayoutScrollListem.target = target; appBarLayoutScrollListem.velocityX = velocityX; appBarLayoutScrollListem.velocityY = velocityY; appBarLayoutScrollListem.consumed = consumed; appBarLayoutScrollListem.totalDy=0; } return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } public boolean onNestedFlingEx(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY, boolean consumed) { return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed); } @Override public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) { super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed); isPositive = dy > 0; } public class AppBarLayoutScrollListem extends RecyclerView.OnScrollListener { AppBarLayout child; View target; CoordinatorLayout coordinatorLayout; float velocityX; float velocityY; boolean consumed; int totalDy=0; public AppBarLayoutScrollListem(Context context){ } @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (child != null && target != null && coordinatorLayout != null) { if (target instanceof RecyclerView) { RecyclerView recyclerView1 = (RecyclerView) target; final View firstChild = recyclerView.getChildAt(0); final int childAdapterPosition = recyclerView.getChildAdapterPosition(firstChild); if (childAdapterPosition == 0 && firstChild.getY() == 0) { int velocityFinal= (int) (velocityY/(float)(child.getMeasuredHeight()+Math.abs(totalDy))*child.getMeasuredHeight()); onNestedFlingEx(coordinatorLayout, child, target, velocityX, velocityFinal, false); } recyclerView1.removeOnScrollListener(this); } } clear(); } } @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); totalDy+=dy; } public void clear() { totalDy=0; child = null; target = null; coordinatorLayout = null; velocityX = 0; velocityY = 0; consumed = false; } } }