问题描述
在商品详情页使用CoordinatorLayout + AppBarLayout + NestScrollView布局组合展示。当向上滚动时,不会产生Fling效果,每当手指离开屏幕,布局就会停止滚动。当向下滚动时没有该问题。
问题分析
嵌套滑动的原理为由NestScrollView接收触摸事件并反馈到父视图,产生联动效果。猜测没有产生Fling效果的原因有可能是在NestScrollView中计算手指滑动速度有错误。
代码分析
关键代码在NestScrollView的OnTouchEvent方法中:
@Override
public boolean onTouchEvent(MotionEvent ev) {
//部分代码省略
//手指滑动事件
case MotionEvent.ACTION_MOVE:
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev,
mActivePointerId);
if (activePointerIndex == -1) {
Log.e(TAG, "Invalid pointerId=" + mActivePointerId + " in onTouchEvent");
break;
}
final int y = (int) MotionEventCompat.getY(ev, activePointerIndex);
int deltaY = mLastMotionY - y;
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
deltaY -= mScrollConsumed[1];
vtev.offsetLocation(0, mScrollOffset[1]);
mNestedYOffset += mScrollOffset[1];
}
if (!mIsBeingDragged && Math.abs(deltaY) > mTouchSlop) {
final ViewParent parent = getParent();
if (parent != null) {
parent.requestDisallowInterceptTouchEvent(true);
}
//此处将mIsBeingGragged赋值为true
mIsBeingDragged = true;
if (deltaY > 0) {
deltaY -= mTouchSlop;
} else {
deltaY += mTouchSlop;
}
}
//部分代码省略
case MotionEvent.ACTION_UP:
//计算手指滑动速率的标准为mIsBeingGragged为True
if (mIsBeingDragged) {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int initialVelocity = (int) VelocityTrackerCompat.getYVelocity(velocityTracker,
mActivePointerId);
if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
flingWithNestedDispatch(-initialVelocity);
} else