这段时间在项目用到 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;
}
}
}