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

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

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



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

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

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

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


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

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">


            android:orientation="vertical"
        android:id="@+id/typeview"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>

布局里面这个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() {
            @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() {
                @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


你可能感兴趣的:(Anndroid学习笔记)