手把手讲解ViewPager翻页特效:向源码学习!

本文深入分析ViewPager源码,揭示其子View的横向排列与滑动逻辑。通过ACTION_MOVE分支,找到处理X轴位移的关键入口。PageTransformer参数变化规律的探索,为实现自定义滑动特效提供了基础。适合Java开发者学习源码和提升技能。
摘要由CSDN通过智能技术生成
  1. }

  2. }

上面代码中,对count进行了两轮循环,其中第一轮是针对lp.isDecortrue的,意为:如果当前view是一个decoration装饰,并不是adapter提供的view则返回true。

显然,我们要探讨的是adapter提供的View是如何摆放的,所以忽略这一块。

而在下面的循环中,可以看到:

  1. child.layout(childLeft, childTop,

  2. childLeft + child.getMeasuredWidth(),

  3. childTop + child.getMeasuredHeight());

这个便是child的排布的核心代码,追溯这4个参数,可以得知:第 1,3 参数表示left,right,他们都和一个 intloff=(int)(childWidth*ii.offset); 挂钩,而 第2,4参数表示 top,bottom,则并没有与任何动态参数相挂钩。

因此可以断定,ViewPager的子View排布,只会存在X轴方向上的位置偏差,在Y方向上会保持上下平齐。

其实还可以继续追溯 intloff=(int)(childWidth*ii.offset); 看看x轴方向上的位置偏差是如何造成的,但是目的已经达到,到有必要的时候再去追查。

确定是横向排布,那么左右滑动逻辑又是怎么样的呢?

找到 onTouchEvent() 方法,并且在其中找到 ACTION_MOVE 逻辑分支:

  1. case MotionEvent.ACTION_MOVE:

  2. if (!mIsBeingDragged) {

  3. final int pointerIndex = ev.findPointerIndex(mActivePointerId);

  4. if (pointerIndex == -1) {

  5. // A child has consumed some touch events and put us into an inconsistent

  6. // state.

  7. needsInvalidate = resetTouch();

  8. break;

  9. }

  10. final float x = ev.getX(pointerIndex);

  11. final float xDiff = Math.abs(x - mLastMotionX);

  12. final float y = ev.getY(pointerIndex);

  13. final float yDiff = Math.abs(y - mLastMotionY);

  14. if (DEBUG) {

  15. Log.v(TAG, "Moved x to " + x + "," + y + " diff=" + xDiff + "," + yDiff);

  16. }

  17. if (xDiff > mTouchSlop && xDiff > yDiff) {

  18. if (DEBUG) Log.v(TAG,

翻页效果,导入源码即可运行。 package sf.hmg.turntest; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.graphics.Region; import android.graphics.drawable.GradientDrawable; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class PageWidget extends View { private static final String TAG = "hmg"; private int mWidth = 480; private int mHeight = 800; private int mCornerX = 0; // 拖拽点对应的页脚 private int mCornerY = 0; private Path mPath0; private Path mPath1; Bitmap mCurPageBitmap = null; // 当前页 Bitmap mCurPageBackBitmap = null; Bitmap mNextPageBitmap = null; PointF mTouch = new PointF(); // 拖拽点 PointF mBezierStart1 = new PointF(); // 贝塞尔曲线起始点 PointF mBezierControl1 = new PointF(); // 贝塞尔曲线控制点 PointF mBeziervertex1 = new PointF(); // 贝塞尔曲线顶点 PointF mBezierEnd1 = new PointF(); // 贝塞尔曲线结束点 PointF mBezierStart2 = new PointF(); // 另一条贝塞尔曲线 PointF mBezierControl2 = new PointF(); PointF mBeziervertex2 = new PointF(); PointF mBezierEnd2 = new PointF(); float mMiddleX; float mMiddleY; float mDegrees; float mTouchToCornerDis; ColorMatrixColorFilter mColorMatrixFilter; Matrix mMatrix; float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f }; boolean mIsRTandLB; // 是否属于右上左下 // for test float mMaxLength = (float) Math.hypot(480, 800); int[] mBackShadowColors; int[] mFrontShadowColors; GradientDrawable mBackShadowDrawableLR; GradientDrawable mBackShadowDrawableRL; GradientDrawable mFolderShadowDrawableLR; GradientDrawable mFolderShadowDrawableRL; GradientDrawable mFrontShadowDrawableHBT; GradientDrawable mFrontShadowDrawableHTB; GradientDrawable mFrontShadowDrawableVLR; GradientDraw
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值