@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childTop = 0;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
child.layout(0, childTop,
child.getMeasuredWidth(), childTop + child.getMeasuredHeight());
childTop = childTop + child.getMeasuredHeight();
}
}
}
完成这些操作后,我们需要在onTouchEvent中进行滑动事件的处理
3.1 完成无限循环滑动滚动
我们的item数量是有限的,如何实现无限循环滚动呢?很简单,以3个item为例子(分别为1,2,3),我们让屏幕显示的是2
如此反复,屏幕所在的位置始终是第2个item所在的位置,这样就实现了我们的无限循环滚动,向下滚动也是如此
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mVelocityTracker == null) {
mVelocityTracker = VelocityTracker.obtain();
}
mVelocityTracker.addMovement(event);
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!mScroller.isFinished()) {
//当上一次滑动没有结束时,再次点击,强制滑动在点击位置结束
mScroller.setFinalY(mScroller.getCurrY());
mScroller.abortAnimation();
scrollTo(0, getScrollY());
}
mDownY = y;
break;
case MotionEvent.ACTION_MOVE:
int realDelta = (int) (mDownY - y);
mDownY = y;
if (mScroller.isFinished()) {
//因为要循环滚动
recycleMove(realDelta);
}
break;
case MotionEvent.ACTION_UP:
mVelocityTracker.computeCurrentVelocity(1000);
float yVelocity = mVelocityTracker.getYVelocity();
//滑动的速度大于规定的速度,或者向上滑动时,上一页页面展现出的高度超过1/2。则设定状态为State.ToPre
if (yVelocity > standerSpeed || ((getScrollY() + mHeight / 2) / mHeight < mStartScreen)) {
mState = State.ToPre;
} else if (yVelocity < -standerSpeed || ((getScrollY() + mHeight / 2) / mHeight > mStartScreen)) {
//滑动的速度大于规定的速度,或者向下滑动时,下一页页面展现出的高度超过1/2。则设定状态为State.ToNext
mState = State.ToNext;
} else {
mState = State.Normal;
}
//根据mState进行相应的变化
changeByState(yVelocity);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
//返回true,消耗点击事件
return true;
}