【★☆☆☆☆】ViewPager是我们常见的控件之一了,而理解ViewPager的实现原理可以让我们后面实现自定义的滑动控件更容易。
在学习本节之前建议先自己实现前两篇文章的效果。
ViewPager的开始流程是从setAdapter()开始,我们这里就不贴源码了,最好的方式是自己去看一遍源码,然后debug一遍,自己一步步走一遍。
ViewPager重写了onMeasure(),我们来看看onMeasure的主要实现
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = View.getDefaultSize(0, widthMeasureSpec);
int height = View.getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childAt = getChildAt(i);
int spec_w = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int spec_h = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
childAt.measure(spec_w, spec_h);
}
}
里面其实就是测量的子View。然后就是onLayout()。
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int childCount = getChildCount();
int width = r - l;
for (int i = 0; i < childCount; i++) {
View childAt = getChildAt(i);
int left = l + width * i;
childAt.layout(left, t, left + childAt.getMeasuredWidth(), t + childAt.getMeasuredHeight());
}
}
这里很关键,实际上就是将子View横向一字排开,有点有点像横向的LinearLayout。下面就是关键一步,重写onTouchEvent(),使ViewPager实现滑动,那么我们如何实现滑动呢?我们可以用scrollTo将内容滑动。
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
rawX = event.getRawX();
break;
case MotionEvent.ACTION_MOVE:
int dx = (int) (event.getRawX() - rawX);
int x = getScrollX() - dx;
scrollTo(x, 0);
rawX = event.getRawX();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
有了上面的代码,我们就能让ViewPager的内容滑动了,上面这些代码也是ViewPager实现的骨干代码。另外我们可以加上限制条件,不让它滚动出显示的区域,然后再MotionEvent.ACTION_UP里用VelocityTracker(速度跟踪器)实现抬起手指后的惯性滑动。
这样,根据上面的代码我们可以自己实现一个简单的ViewPager,效果如下:
自己手写一个ViewPager比看10遍代码还要顶用。上面实现的源码和sample已经上传github,项目会持续更新!
我的github:https://github.com/pop1234o/CustomViewApp