Android学习笔记---实现网络图片翻页效果

来源:互联网 发布:mac哈尔滨有专柜么 编辑:程序博客网 时间:2024/05/21 23:40

每天一个小目标,早晚单车变摩托

言归正传,今天又接到了一个需求,就是要使图片翻页的时候模仿电子书的翻页效果,大概是什么样子 先来看下效果图



大概是就是这么一个样子,接下来就进入代码环节

注:以下自定义组件以及工具类都非本人亲自编写,均属于互联网

开源作品,本篇博客只讲使用,不讲原理

首先我们先来复制一个自定义组件到我们自己的项目里分别是


import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;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.view.MotionEvent;import android.view.View;import android.widget.Scroller;public class Pager extends View {   private int mWidth = 1280;   private int mHeight = 768;   private int mCornerX = 0; // 拖拽点对应的页脚   private int mCornerY = 0;   private Path mPath0;   private Path mPath1;   Bitmap mCurPageBitmap = 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; // 是否属于右、上、左、下   float mMaxLength = (float) Math.hypot(mWidth, mHeight);   int[] mBackShadowColors;   int[] mFrontShadowColors;   GradientDrawable mBackShadowDrawableLR;   GradientDrawable mBackShadowDrawableRL;   GradientDrawable mFolderShadowDrawableLR;   GradientDrawable mFolderShadowDrawableRL;   GradientDrawable mFrontShadowDrawableHBT;   GradientDrawable mFrontShadowDrawableHTB;   GradientDrawable mFrontShadowDrawableVLR;   GradientDrawable mFrontShadowDrawableVRL;   Paint mPaint;   Scroller mScroller;   public Pager(Context context, int screenWidth, int screenHeight) {      super(context);            this.mWidth = screenWidth;    // Pager 宽和高      this.mHeight = screenHeight;      mPath0 = new Path();      mPath1 = new Path();      createDrawable();      mPaint = new Paint();      mPaint.setStyle(Paint.Style.FILL);      ColorMatrix cm = new ColorMatrix();      float array[] = { 0.55f, 0, 0, 0, 80.0f, 0, 0.55f, 0, 0, 80.0f, 0, 0,            0.55f, 0, 80.0f, 0, 0, 0, 0.2f, 0 };      cm.set(array);      mColorMatrixFilter = new ColorMatrixColorFilter(cm);      mMatrix = new Matrix();      mScroller = new Scroller(getContext());      mTouch.x = 0.01f;     // 不让x,y为0,否则在点计算时会有问题      mTouch.y = 0.01f;   }   /** 计算拖拽点对应的拖拽脚 */   public void calcCornerXY(float x, float y) {      if (x <= mWidth / 2)         mCornerX = 0;      else         mCornerX = mWidth;      if (y <= mHeight / 2)         mCornerY = 0;      else         mCornerY = mHeight;      if ((mCornerX == 0 && mCornerY == mHeight) || (mCornerX == mWidth && mCornerY == 0))         mIsRTandLB = true;      else         mIsRTandLB = false;   }   public boolean doTouchEvent(MotionEvent event) {      if (event.getAction() == MotionEvent.ACTION_MOVE) {         mTouch.x = event.getX();         mTouch.y = event.getY();         this.postInvalidate();      }      if (event.getAction() == MotionEvent.ACTION_DOWN) {         mTouch.x = event.getX();         mTouch.y = event.getY();         // calcCornerXY(mTouch.x, mTouch.y);         // this.postInvalidate();      }      if (event.getAction() == MotionEvent.ACTION_UP) {         if (canDragOver()) {            startAnimation(1200);         } else {            mTouch.x = mCornerX - 0.09f;            mTouch.y = mCornerY - 0.09f;         }         this.postInvalidate();      }      // return super.onTouchEvent(event);      return true;   }   /** 求解直线P1P2和直线P3P4的交点坐标  */   public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {      PointF CrossP = new PointF();      // 二元函数通式: y=ax+b      float a1 = (P2.y - P1.y) / (P2.x - P1.x);      float b1 = ((P1.x * P2.y) - (P2.x * P1.y)) / (P1.x - P2.x);      float a2 = (P4.y - P3.y) / (P4.x - P3.x);      float b2 = ((P3.x * P4.y) - (P4.x * P3.y)) / (P3.x - P4.x);      CrossP.x = (b2 - b1) / (a1 - a2);      CrossP.y = a1 * CrossP.x + b1;      return CrossP;   }   private void calcPoints() {      mMiddleX = (mTouch.x + mCornerX) / 2;      mMiddleY = (mTouch.y + mCornerY) / 2;      mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);      mBezierControl1.y = mCornerY;      mBezierControl2.x = mCornerX;      mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);      mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;      mBezierStart1.y = mCornerY;      // 当mBezierStart1.x < 0或者mBezierStart1.x > 480时      // 如果继续翻页,会出现BUG故在此限制      if (mTouch.x > 0 && mTouch.x < mWidth) {         if (mBezierStart1.x < 0 || mBezierStart1.x > mWidth) {            if (mBezierStart1.x < 0)               mBezierStart1.x = mWidth - mBezierStart1.x;            float f1 = Math.abs(mCornerX - mTouch.x);            float f2 = mWidth * f1 / mBezierStart1.x;            mTouch.x = Math.abs(mCornerX - f2);            float f3 = Math.abs(mCornerX - mTouch.x)                  * Math.abs(mCornerY - mTouch.y) / f1;            mTouch.y = Math.abs(mCornerY - f3);            mMiddleX = (mTouch.x + mCornerX) / 2;            mMiddleY = (mTouch.y + mCornerY) / 2;            mBezierControl1.x = mMiddleX - (mCornerY - mMiddleY) * (mCornerY - mMiddleY) / (mCornerX - mMiddleX);            mBezierControl1.y = mCornerY;            mBezierControl2.x = mCornerX;            mBezierControl2.y = mMiddleY - (mCornerX - mMiddleX) * (mCornerX - mMiddleX) / (mCornerY - mMiddleY);            mBezierStart1.x = mBezierControl1.x - (mCornerX - mBezierControl1.x) / 2;         }      }      mBezierStart2.x = mCornerX;      mBezierStart2.y = mBezierControl2.y - (mCornerY - mBezierControl2.y) / 2;      mTouchToCornerDis = (float) Math.hypot((mTouch.x - mCornerX), (mTouch.y - mCornerY));      mBezierEnd1 = getCross(mTouch, mBezierControl1, mBezierStart1, mBezierStart2);      mBezierEnd2 = getCross(mTouch, mBezierControl2, mBezierStart1, mBezierStart2);      /*       * mBeziervertex1.x 推导       * ((mBezierStart1.x+mBezierEnd1.x)/2+mBezierControl1.x)/2 化简等价于       * (mBezierStart1.x+ 2*mBezierControl1.x+mBezierEnd1.x) / 4       */      mBeziervertex1.x = (mBezierStart1.x + 2 * mBezierControl1.x + mBezierEnd1.x) / 4;      mBeziervertex1.y = (2 * mBezierControl1.y + mBezierStart1.y + mBezierEnd1.y) / 4;      mBeziervertex2.x = (mBezierStart2.x + 2 * mBezierControl2.x + mBezierEnd2.x) / 4;      mBeziervertex2.y = (2 * mBezierControl2.y + mBezierStart2.y + mBezierEnd2.y) / 4;   }   private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap, Path path) {      mPath0.reset();      mPath0.moveTo(mBezierStart1.x, mBezierStart1.y);      mPath0.quadTo(mBezierControl1.x, mBezierControl1.y, mBezierEnd1.x, mBezierEnd1.y);      mPath0.lineTo(mTouch.x, mTouch.y);      mPath0.lineTo(mBezierEnd2.x, mBezierEnd2.y);      mPath0.quadTo(mBezierControl2.x, mBezierControl2.y, mBezierStart2.x, mBezierStart2.y);      mPath0.lineTo(mCornerX, mCornerY);      mPath0.close();      canvas.save();      canvas.clipPath(path, Region.Op.XOR);      canvas.drawBitmap(bitmap, 0, 0, null);      canvas.restore();   }   private void drawNextPageAreaAndShadow(Canvas canvas, Bitmap bitmap) {      mPath1.reset();      mPath1.moveTo(mBezierStart1.x, mBezierStart1.y);      mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);      mPath1.lineTo(mBeziervertex2.x, mBeziervertex2.y);      mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);      mPath1.lineTo(mCornerX, mCornerY);      mPath1.close();      mDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl1.x - mCornerX, mBezierControl2.y - mCornerY));      int leftx;      int rightx;      GradientDrawable mBackShadowDrawable;      if (mIsRTandLB) {         leftx = (int) (mBezierStart1.x);         rightx = (int) (mBezierStart1.x + mTouchToCornerDis / 4);         mBackShadowDrawable = mBackShadowDrawableLR;      } else {         leftx = (int) (mBezierStart1.x - mTouchToCornerDis / 4);         rightx = (int) mBezierStart1.x;         mBackShadowDrawable = mBackShadowDrawableRL;      }      canvas.save();      canvas.clipPath(mPath0);      canvas.clipPath(mPath1, Region.Op.INTERSECT);      canvas.drawBitmap(bitmap, 0, 0, null);      canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);      mBackShadowDrawable.setBounds(leftx, (int) mBezierStart1.y, rightx, (int) (mMaxLength + mBezierStart1.y));      mBackShadowDrawable.draw(canvas);      canvas.restore();   }   public void setBitmaps(Bitmap bm1, Bitmap bm2) {      mCurPageBitmap = bm1;      mNextPageBitmap = bm2;   }   public void setScreen(int w, int h) {      mWidth = w;      mHeight = h;   }   @Override   protected void onDraw(Canvas canvas) {      canvas.drawColor(0xFFAAAAAA);      calcPoints();      drawCurrentPageArea(canvas, mCurPageBitmap, mPath0);      drawNextPageAreaAndShadow(canvas, mNextPageBitmap);      drawCurrentPageShadow(canvas);      drawCurrentBackArea(canvas, mCurPageBitmap);   }   /** 创建阴影的GradientDrawable */   private void createDrawable() {      int[] color = { 0x333333, 0xb0333333 };      mFolderShadowDrawableRL = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, color);      mFolderShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mFolderShadowDrawableLR = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, color);      mFolderShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mBackShadowColors = new int[] { 0xff111111, 0x111111 };      mBackShadowDrawableRL = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, mBackShadowColors);      mBackShadowDrawableRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mBackShadowDrawableLR = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, mBackShadowColors);      mBackShadowDrawableLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mFrontShadowColors = new int[] { 0x80111111, 0x111111 };      mFrontShadowDrawableVLR = new GradientDrawable(GradientDrawable.Orientation.LEFT_RIGHT, mFrontShadowColors);      mFrontShadowDrawableVLR.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mFrontShadowDrawableVRL = new GradientDrawable(GradientDrawable.Orientation.RIGHT_LEFT, mFrontShadowColors);      mFrontShadowDrawableVRL.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mFrontShadowDrawableHTB = new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM, mFrontShadowColors);      mFrontShadowDrawableHTB.setGradientType(GradientDrawable.LINEAR_GRADIENT);      mFrontShadowDrawableHBT = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, mFrontShadowColors);      mFrontShadowDrawableHBT.setGradientType(GradientDrawable.LINEAR_GRADIENT);   }   /** 绘制翻起页的阴影 */   public void drawCurrentPageShadow(Canvas canvas) {      double degree;      if (mIsRTandLB) {         degree = Math.PI / 4 - Math.atan2(mBezierControl1.y - mTouch.y, mTouch.x - mBezierControl1.x);      } else {         degree = Math.PI / 4 - Math.atan2(mTouch.y - mBezierControl1.y, mTouch.x - mBezierControl1.x);      }      // 翻起页阴影顶点与touch点的距离      double d1 = (float) 25 * 1.414 * Math.cos(degree);      double d2 = (float) 25 * 1.414 * Math.sin(degree);      float x = (float) (mTouch.x + d1);      float y;      if (mIsRTandLB) {         y = (float) (mTouch.y + d2);      } else {         y = (float) (mTouch.y - d2);      }      mPath1.reset();      mPath1.moveTo(x, y);      mPath1.lineTo(mTouch.x, mTouch.y);      mPath1.lineTo(mBezierControl1.x, mBezierControl1.y);      mPath1.lineTo(mBezierStart1.x, mBezierStart1.y);      mPath1.close();      float rotateDegrees;      canvas.save();      canvas.clipPath(mPath0, Region.Op.XOR);      canvas.clipPath(mPath1, Region.Op.INTERSECT);      int leftx;      int rightx;      GradientDrawable mCurrentPageShadow;      if (mIsRTandLB) {         leftx = (int) (mBezierControl1.x);         rightx = (int) mBezierControl1.x + 25;         mCurrentPageShadow = mFrontShadowDrawableVLR;      } else {         leftx = (int) (mBezierControl1.x - 25);         rightx = (int) mBezierControl1.x + 1;         mCurrentPageShadow = mFrontShadowDrawableVRL;      }      rotateDegrees = (float) Math.toDegrees(Math.atan2(mTouch.x - mBezierControl1.x, mBezierControl1.y - mTouch.y));      canvas.rotate(rotateDegrees, mBezierControl1.x, mBezierControl1.y);      mCurrentPageShadow.setBounds(leftx, (int) (mBezierControl1.y - mMaxLength), rightx, (int) (mBezierControl1.y));      mCurrentPageShadow.draw(canvas);      canvas.restore();      mPath1.reset();      mPath1.moveTo(x, y);      mPath1.lineTo(mTouch.x, mTouch.y);      mPath1.lineTo(mBezierControl2.x, mBezierControl2.y);      mPath1.lineTo(mBezierStart2.x, mBezierStart2.y);      mPath1.close();      canvas.save();      canvas.clipPath(mPath0, Region.Op.XOR);      canvas.clipPath(mPath1, Region.Op.INTERSECT);      if (mIsRTandLB) {         leftx = (int) (mBezierControl2.y);         rightx = (int) (mBezierControl2.y + 25);         mCurrentPageShadow = mFrontShadowDrawableHTB;      } else {         leftx = (int) (mBezierControl2.y - 25);         rightx = (int) (mBezierControl2.y + 1);         mCurrentPageShadow = mFrontShadowDrawableHBT;      }      rotateDegrees = (float) Math.toDegrees(Math.atan2(mBezierControl2.y - mTouch.y, mBezierControl2.x - mTouch.x));      canvas.rotate(rotateDegrees, mBezierControl2.x, mBezierControl2.y);      float temp;      if (mBezierControl2.y < 0)         temp = mBezierControl2.y - mHeight;      else         temp = mBezierControl2.y;      int hmg = (int) Math.hypot(mBezierControl2.x, temp);      if (hmg > mMaxLength)         mCurrentPageShadow.setBounds((int) (mBezierControl2.x - 25) - hmg, leftx, (int) (mBezierControl2.x + mMaxLength) - hmg, rightx);      else         mCurrentPageShadow.setBounds((int) (mBezierControl2.x - mMaxLength), leftx, (int) (mBezierControl2.x), rightx);      mCurrentPageShadow.draw(canvas);      canvas.restore();   }   /** 绘制翻起页背面 */   private void drawCurrentBackArea(Canvas canvas, Bitmap bitmap) {      int i = (int) (mBezierStart1.x + mBezierControl1.x) / 2;      float f1 = Math.abs(i - mBezierControl1.x);      int i1 = (int) (mBezierStart2.y + mBezierControl2.y) / 2;      float f2 = Math.abs(i1 - mBezierControl2.y);      float f3 = Math.min(f1, f2);      mPath1.reset();      mPath1.moveTo(mBeziervertex2.x, mBeziervertex2.y);      mPath1.lineTo(mBeziervertex1.x, mBeziervertex1.y);      mPath1.lineTo(mBezierEnd1.x, mBezierEnd1.y);      mPath1.lineTo(mTouch.x, mTouch.y);      mPath1.lineTo(mBezierEnd2.x, mBezierEnd2.y);      mPath1.close();      GradientDrawable mFolderShadowDrawable;      int left;      int right;      if (mIsRTandLB) {         left = (int) (mBezierStart1.x - 1);         right = (int) (mBezierStart1.x + f3 + 1);         mFolderShadowDrawable = mFolderShadowDrawableLR;      } else {         left = (int) (mBezierStart1.x - f3 - 1);         right = (int) (mBezierStart1.x + 1);         mFolderShadowDrawable = mFolderShadowDrawableRL;      }      canvas.save();      canvas.clipPath(mPath0);      canvas.clipPath(mPath1, Region.Op.INTERSECT);      mPaint.setColorFilter(mColorMatrixFilter);      float dis = (float) Math.hypot(mCornerX - mBezierControl1.x, mBezierControl2.y - mCornerY);      float f8 = (mCornerX - mBezierControl1.x) / dis;      float f9 = (mBezierControl2.y - mCornerY) / dis;      mMatrixArray[0] = 1 - 2 * f9 * f9;      mMatrixArray[1] = 2 * f8 * f9;      mMatrixArray[3] = mMatrixArray[1];      mMatrixArray[4] = 1 - 2 * f8 * f8;      mMatrix.reset();      mMatrix.setValues(mMatrixArray);      mMatrix.preTranslate(-mBezierControl1.x, -mBezierControl1.y);      mMatrix.postTranslate(mBezierControl1.x, mBezierControl1.y);      canvas.drawBitmap(bitmap, mMatrix, mPaint);      //canvas.drawBitmap(bitmap, mMatrix, null);      mPaint.setColorFilter(null);      canvas.rotate(mDegrees, mBezierStart1.x, mBezierStart1.y);      mFolderShadowDrawable.setBounds(left, (int) mBezierStart1.y, right, (int) (mBezierStart1.y + mMaxLength));      mFolderShadowDrawable.draw(canvas);      canvas.restore();   }   public void computeScroll() {      super.computeScroll();      if (mScroller.computeScrollOffset()) {         float x = mScroller.getCurrX();         float y = mScroller.getCurrY();         mTouch.x = x;         mTouch.y = y;         postInvalidate();      }   }   private void startAnimation(int delayMillis) {      int dx, dy; // dx 水平方向滑动的距离,负值会使滚动向左滚动  dy 垂直方向滑动的距离,负值会使滚动向上滚动      if (mCornerX > 0) {         dx = -(int) (mWidth + mTouch.x);      } else {         dx = (int) (mWidth - mTouch.x + mWidth);      }      if (mCornerY > 0) {         dy = (int) (mHeight - mTouch.y);      } else {         dy = (int) (1 - mTouch.y); // 防止mTouch.y最终变为0      }      mScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy, delayMillis);   }   public void abortAnimation() {      if (!mScroller.isFinished()) {         mScroller.abortAnimation();      }   }   public boolean canDragOver() {      if (mTouchToCornerDis > mWidth / 10)         return true;      return false;   }   /** 是否从左边翻向右边  */   public boolean DragToRight() {      if (mCornerX > 0)         return false;      return true;   }

还有一个工具类

import android.content.Context;import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Paint;import android.graphics.Paint.Align;public class PagerFactory {   private Context mContext;   private Bitmap m_book_bg = null;   private int m_backColor = 0xffff9e85;  // 背景颜色   private boolean m_isfirstPage,m_islastPage;   private Paint mPaint;   public PagerFactory(Context context) {      mContext = context;      mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);      mPaint.setTextAlign(Align.LEFT);      mPaint.setColor(m_backColor);   }   public void onDraw(Canvas c) {      if (m_book_bg == null)         c.drawColor(m_backColor);      else         c.drawBitmap(m_book_bg, 0, 0, null);   }   public void onDraw(Canvas c, Bitmap bitmap){      c.drawBitmap(bitmap, 0, 0, null);   }   public void setBgBitmap(Bitmap BG) {      m_book_bg = BG;   }

好了 既然东西已经有了 那么怎么用呢

我们在xml里面写一个

acitivity.main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"    android:layout_width="match_parent" android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.ht.sks.mypage.MainActivity">    <LinearLayout        android:orientation="vertical"        android:id="@+id/typeview"        android:layout_width="match_parent"        android:layout_height="300dp"/></RelativeLayout>

布局里面这个LinearLayout主要是用来展示图片的位置,这样就可以随心所欲的使用了,


下面在代码中初始化翻页组件


   /**     * 初始化组件     */    private void initView() {        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();        screenWidth = displayMetrics.widthPixels;        screenHeight = displayMetrics.heightPixels;        pager = new Pager(this, screenWidth, screenHeight);        //下面这段代码是全屏的,不太方便使用,注掉/*        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);        addContentView(pager, layoutParams);*/        //把咱们的图片加入到之前的布局里        linearLayout.addView(pager);        //图片类型        mCurPageBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);        mNextPageBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);        mCurPageCanvas = new Canvas(mCurPageBitmap);        mNextPageCanvas = new Canvas(mNextPageBitmap);        pagerFactory = new PagerFactory(getApplicationContext());        pager.setBitmaps(mCurPageBitmap, mCurPageBitmap);        //翻页监听        pager.setOnTouchListener(new View.OnTouchListener() {            private int count = pages.length;            private int currentIndex = 0;            private int lastIndex = 0;            private Bitmap lastBitmap = null;            @Override            public boolean onTouch(View v, MotionEvent e) {                boolean ret = false;                if (v == pager) {                    if (e.getAction() == MotionEvent.ACTION_DOWN) {                        pager.calcCornerXY(e.getX(), e.getY());                        lastBitmap = currentBitmap;                        lastIndex = currentIndex;                        pagerFactory.onDraw(mCurPageCanvas, currentBitmap);                        if (pager.DragToRight()) {    // 向右滑动,显示前一页                            if (currentIndex == 0) return false;                            pager.abortAnimation();                            currentIndex--;                            loadImage(mNextPageCanvas, currentIndex);                            Toast.makeText(MainActivity.this, "当前第"+currentIndex+"页", Toast.LENGTH_SHORT).show();                        } else {        // 向左滑动,显示后一页                            if (currentIndex + 1 == count) return false;                            pager.abortAnimation();                            currentIndex++;                            //加载图片并显示出来                            loadImage(mNextPageCanvas, currentIndex);                            Toast.makeText(MainActivity.this, "当前第"+currentIndex+"页", Toast.LENGTH_SHORT).show();                        }                    } else if (e.getAction() == MotionEvent.ACTION_MOVE) {                    } else if (e.getAction() == MotionEvent.ACTION_UP) {                        if (!pager.canDragOver()) {                            currentIndex = lastIndex;                            currentBitmap = lastBitmap;                        }                    }                    ret = pager.doTouchEvent(e);                    return ret;                }                return false;            }        });    }

以及请求网络图片并设置的方法


/** * 请求图片并显示 * @param canvas * @param index */private void loadImage(final Canvas canvas, int index) {    //使用封装的Fresco图片加载框架的工具类请求得到网络图片的Bitmap        FrescoLoadUtil.getInstance().loadImageBitmap(pages[index], new FrescoBitmapCallback<Bitmap>() {            @Override            public void onSuccess(Uri uri, Bitmap result) {                //原来的大小                int width = result.getWidth();                int height = result.getHeight();                // 设置想要的大小                int newWidth = linearLayout.getWidth();                int newHeight = linearLayout.getHeight();                // 计算缩放比例                float scaleWidth = ((float) newWidth) / width;                float scaleHeight = ((float) newHeight) / height;                // 取得想要缩放的matrix参数                Matrix matrix = new Matrix();                matrix.postScale(scaleWidth, scaleHeight);                // 修改得到的bitmap的大小,根据个人需求自行设置                Bitmap bitMap = Bitmap.createBitmap(result, 0, 0, width, height, matrix, true);                currentBitmap = bitMap;                //传入得到的图片                pagerFactory.onDraw(canvas, bitMap);                pager.setBitmaps(mCurPageBitmap, mNextPageBitmap);                pager.postInvalidate();            }            @Override            public void onFailure(Uri uri, Throwable throwable) {            }            @Override            public void onCancel(Uri uri) {            }        });}

好了 到这里 一个翻页效果就可以完成了


整体代码


import android.graphics.Bitmap;import android.graphics.Canvas;import android.graphics.Matrix;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.MotionEvent;import android.view.View;import android.widget.LinearLayout;import android.widget.Toast;import com.facebook.drawee.backends.pipeline.Fresco;public class MainActivity extends AppCompatActivity {    private LinearLayout linearLayout;    private Pager pager;    private PagerFactory pagerFactory;    private Bitmap currentBitmap, mCurPageBitmap, mNextPageBitmap;    private Canvas mCurPageCanvas, mNextPageCanvas;    //图片数组    private static final String[] pages = {"http://pic.58pic.com/58pic/15/62/55/37Z58PICmtR_1024.jpg","http://pic1.16pic.com/00/03/24/16pic_324498_b.jpg","http://pic2.cxtuku.com/00/15/88/b305b7673527.jpg","http://pic18.nipic.com/20120105/293411_145330148396_2.jpg", "http://pic36.nipic.com/20131224/9904897_144358081000_2.jpg", "http://img2.makepolo.net/images/formals/img/product/430/174/6356faae42f9a838bfc036bb49d74656.jpg"};    private int screenWidth;    private int screenHeight;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化框架        Fresco.initialize(this);        //初始化布局;        linearLayout = (LinearLayout) findViewById(R.id.typeview);        //初始化自定义组件        initView();        //默认加载第一张图        loadImage(mNextPageCanvas, 0);    }    /**     * 初始化组件     */    private void initView() {        DisplayMetrics displayMetrics = getResources().getDisplayMetrics();        screenWidth = displayMetrics.widthPixels;        screenHeight = displayMetrics.heightPixels;        pager = new Pager(this, screenWidth, screenHeight);        //下面这段代码是全屏的,不太方便使用,注掉/*        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);        addContentView(pager, layoutParams);*/        //把咱们的图片加入到之前的布局里        linearLayout.addView(pager);        //图片类型        mCurPageBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);        mNextPageBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);        mCurPageCanvas = new Canvas(mCurPageBitmap);        mNextPageCanvas = new Canvas(mNextPageBitmap);        pagerFactory = new PagerFactory(MainActivity.this);        pager.setBitmaps(mCurPageBitmap, mCurPageBitmap);        //翻页监听        pager.setOnTouchListener(new View.OnTouchListener() {            private int count = pages.length;            private int currentIndex = 0;            private int lastIndex = 0;            private Bitmap lastBitmap = null;            @Override            public boolean onTouch(View v, MotionEvent e) {                boolean ret = false;                if (v == pager) {                    if (e.getAction() == MotionEvent.ACTION_DOWN) {                        pager.calcCornerXY(e.getX(), e.getY());                        lastBitmap = currentBitmap;                        lastIndex = currentIndex;                        pagerFactory.onDraw(mCurPageCanvas, currentBitmap);                        if (pager.DragToRight()) {    // 向右滑动,显示前一页                            if (currentIndex == 0) return false;                            pager.abortAnimation();                            currentIndex--;                            loadImage(mNextPageCanvas, currentIndex);                            Toast.makeText(MainActivity.this, "当前第"+currentIndex+"页", Toast.LENGTH_SHORT).show();                        } else {        // 向左滑动,显示后一页                            if (currentIndex + 1 == count) return false;                            pager.abortAnimation();                            currentIndex++;                            //加载图片并显示出来                            loadImage(mNextPageCanvas, currentIndex);                            Toast.makeText(MainActivity.this, "当前第"+currentIndex+"页", Toast.LENGTH_SHORT).show();                        }                    } else if (e.getAction() == MotionEvent.ACTION_MOVE) {                    } else if (e.getAction() == MotionEvent.ACTION_UP) {                        if (!pager.canDragOver()) {                            currentIndex = lastIndex;                            currentBitmap = lastBitmap;                        }                    }                    ret = pager.doTouchEvent(e);                    return ret;                }                return false;            }        });    }    /**     * 请求图片并显示     * @param canvas     * @param index     */    private void loadImage(final Canvas canvas, int index) {        //使用封装的Fresco图片加载框架的工具类请求得到网络图片的Bitmap            FrescoLoadUtil.getInstance().loadImageBitmap(pages[index], new FrescoBitmapCallback<Bitmap>() {                @Override                public void onSuccess(Uri uri, Bitmap result) {                    //原来的大小                    int width = result.getWidth();                    int height = result.getHeight();                    // 设置想要的大小                    int newWidth = linearLayout.getWidth();                    int newHeight = linearLayout.getHeight();                    // 计算缩放比例                    float scaleWidth = ((float) newWidth) / width;                    float scaleHeight = ((float) newHeight) / height;                    // 取得想要缩放的matrix参数                    Matrix matrix = new Matrix();                    matrix.postScale(scaleWidth, scaleHeight);                    // 修改得到的bitmap的大小,根据个人需求自行设置                    Bitmap bitMap = Bitmap.createBitmap(result, 0, 0, width, height, matrix, true);                    currentBitmap = bitMap;                    //传入得到的图片                    pagerFactory.onDraw(canvas, bitMap);                    pager.setBitmaps(mCurPageBitmap, mNextPageBitmap);                    pager.postInvalidate();                }                @Override                public void onFailure(Uri uri, Throwable throwable) {                }                @Override                public void onCancel(Uri uri) {                }            });    }}

好了到这一步 我们的工作就以及完成了,让我们来看看效果吧




demo下载地址

http://download.csdn.net/download/crackgmkey/10018821