您的位置:首页 > 理论基础 > 计算机网络

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

2017-10-12 22:22 369 查看

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

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



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

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

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

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

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;

1fff8
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: