note
note copied to clipboard
Android 翻页特效 EffectReadView
package cn.yicha.tuijian.model.novel.read;
import cn.yicha.tuijian.model.novel.onShowListener;
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.Typeface;
import android.graphics.drawable.GradientDrawable;
import android.view.MotionEvent;
import android.widget.Scroller;
/**
* 自定义View,实现翻页特效
* <br/>改自http://blog.csdn.net/hmg25/article/details/6342539
*
* <br/> 继承自HorizontalReadView,不再实现HorizontalReadView已有的读取设置等方法,只改动与HorizontalReadView不一致的地方。
*
* @author gudh
* @data 2014-1-7
*/
public class EffectReadView extends HorizontalReadView {
// 阴影相关
private GradientDrawable mBackShadowDrawableLR;
private GradientDrawable mBackShadowDrawableRL;
private GradientDrawable mFolderShadowDrawableLR;
private GradientDrawable mFolderShadowDrawableRL;
private GradientDrawable mFrontShadowDrawableHBT;
private GradientDrawable mFrontShadowDrawableHTB;
private GradientDrawable mFrontShadowDrawableVLR;
private GradientDrawable mFrontShadowDrawableVRL;
private PointF mBezierStart1 = new PointF(); // 贝塞尔曲线起始点
private PointF mBezierControl1 = new PointF(); // 贝塞尔曲线控制点
private PointF mBezierVertex1 = new PointF(); // 贝塞尔曲线顶点
private PointF mBezierEnd1 = new PointF(); // 贝塞尔曲线结束点
private PointF mBezierStart2 = new PointF(); // 另一条贝塞尔曲线
private PointF mBezierControl2 = new PointF();
private PointF mBezierVertex2 = new PointF();
private PointF mBezierEnd2 = new PointF();
private float mMaxLength = (float) Math.hypot(screenW, screenH); // 对角线长
private PointF mTouch = new PointF(); // 拖拽点
private int mCornerX = 0; // 拖拽点对应的页脚,计算出来的
private int mCornerY = 0;
private float mDegrees; // 旋转的角度
private float mTouchToCornerDis; // 触点到页脚的距离
private boolean mIsRTOrLB; // 是否属于右上或左下,阴影方向
private Path mPath0; // 当前页与背面的线
private Path mPath1; // 背面与下一页的线
private Paint mPaint; // 画笔,背面颜色处理
private Scroller mScroller; // 滑动器
private Bitmap mCurPageBitmap = null; // 当前页
private Bitmap mNextPageBitmap = null;
private Matrix mMatrix; // 背面形状
private float[] mMatrixArray = { 0, 0, 0, 0, 0, 0, 0, 0, 1.0f };
public EffectReadView(Context context,int fontSize,int[] rgb,Typeface fontFamliy,onShowListener mOnShow){
super(context, fontSize, rgb, fontFamliy, mOnShow);
// 创建阴影的GradientDrawable
createDrawable();
mPath0 = new Path();
mPath1 = new Path();
// 颜色矩阵
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 };
ColorMatrix cm = new ColorMatrix();
cm.set(array);
ColorMatrixColorFilter mColorMatrixFilter = new ColorMatrixColorFilter(
cm);
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setColorFilter(mColorMatrixFilter);
mMatrix = new Matrix();
mScroller = new Scroller(getContext());
resetCorner();
}
/**
* 重置触点
*/
public void resetCorner(){
// 初始化触点,不让x,y为0,否则在点计算时会有问题
mTouch.x = 0.01f;
mTouch.y = 0.01f;
calcCornerXY(mTouch.x, mTouch.y);
}
/**
* 处理拖动和弹起的操作事件
*
* @param event
* @return
*/
public boolean doTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mTouch.x = event.getX();
mTouch.y = event.getY();
this.postInvalidate();
} else if (event.getAction() == MotionEvent.ACTION_UP) {
if (canDragOver()) {
startAnimation(1200);
} else {
mTouch.x = mCornerX - 0.09f;
mTouch.y = mCornerY - 0.09f;
}
this.postInvalidate();
}
return true;
}
/**
* 画当前页区域
*
* @param canvas
* @param bitmap
* @param path
*/
private void drawCurrentPageArea(Canvas canvas, Bitmap bitmap) {
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(mPath0, Region.Op.XOR);
canvas.drawBitmap(bitmap, 0, 0, null);
canvas.restore();
}
/**
* 画下一页和背景页
*
* @param canvas
* @param bitmap
*/
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 (mIsRTOrLB) {
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 drawCurrentPageShadow(Canvas canvas) {
double degree;
if (mIsRTOrLB) {
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 (mIsRTOrLB) {
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 (mIsRTOrLB) {
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 (mIsRTOrLB) {
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 - screenH;
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 (mIsRTOrLB) {
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);
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();
}
/**
* 在指定时间内滑动出去
*
* @param delayMillis
*/
private void startAnimation(int delayMillis) {
int dx, dy;
// dx 水平方向滑动的距离,负值会使滚动向左滚动
// dy 垂直方向滑动的距离,负值会使滚动向上滚动
if (mCornerX > 0) {
dx = -(int) (screenW + mTouch.x);
} else {
dx = (int) (screenW - mTouch.x + screenW);
}
if (mCornerY > 0) {
dy = (int) (screenH - mTouch.y);
} else {
dy = (int) (1 - mTouch.y); // 防止mTouch.y最终变为0
}
mScroller.startScroll((int) mTouch.x, (int) mTouch.y, dx, dy,
delayMillis);
}
/**
* 滑动过程处理
*/
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 calcPoints() {
// 触电到页脚的中点
float mMiddleX = (mTouch.x + mCornerX) / 2;
float 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 < screenW) {
if (mBezierStart1.x < 0 || mBezierStart1.x > screenW) {
if (mBezierStart1.x < 0) {
mBezierStart1.x = screenW - mBezierStart1.x;
}
float f1 = Math.abs(mCornerX - mTouch.x);
float f2 = screenW * 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;
}
/**
* 如果没有停止,则终止滑动
*/
public void abortAnimation() {
if (!mScroller.isFinished()) {
mScroller.abortAnimation();
}
}
/**
* 判断是否需要继续自动翻页至结束
*
* @return
*/
public boolean canDragOver() {
// 拖动距离超过宽度十分之一,则需要翻页,否则不需要
if (mTouchToCornerDis > screenW / 10) {
return true;
}
return false;
}
/**
* 是否从左边翻向右边
*/
public boolean DragToRight() {
return mCornerX == 0;
}
/**
* 计算拖拽点对应的拖拽脚
*/
public void calcCornerXY(float x, float y) {
mTouch.x = x;
mTouch.y = y;
if (x <= screenW / 2) {
mCornerX = 0;
} else {
mCornerX = screenW;
}
if (y <= screenH / 2) {
mCornerY = 0;
} else {
mCornerY = screenH;
}
if ((mCornerX == 0 && mCornerY == screenH)
|| (mCornerX == screenW && mCornerY == 0)) {
mIsRTOrLB = true; // corner在左下角或者右上角
} else {
mIsRTOrLB = false;
}
}
/**
* 创建阴影的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);
int[] 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);
int[] 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);
}
/**
* 求解直线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;
}
/**
* 绘图方法
*/
@Override
protected void onDraw(Canvas canvas) {
if(mNextPageBitmap == mCurPageBitmap){
this.resetCorner();
}
// 计算各个点
calcPoints();
canvas.drawColor(0xFFAAAAAA);
drawCurrentPageArea(canvas, mCurPageBitmap);
drawCurrentPageShadow(canvas);
drawNextPageAreaAndShadow(canvas, mNextPageBitmap);
drawCurrentBackArea(canvas, mCurPageBitmap);
// 绘制title
if (title != null) {
canvas.drawText(title, super.screenW / 2
- (titlePaint.measureText(title) / 2), this.titleH,
titlePaint);
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
showMenu=false;
touchStartX = event.getX();
touchStartY = event.getY();
// 记录 指针指向恢复使用
charStartPosTmp = charStartPos;
charEndPosTmp = charEndPos;
touchType = parseEvent(event.getX(), event.getY());
if(touchType == 0){
// 如果为弹框,则重设按点
this.resetCorner();
}else{
this.abortAnimation();
this.calcCornerXY(touchStartX, touchStartY);
}
switch (touchType) {
case -1:// prv
if (touchLock)
return false;
this.oldX = event.getX();
oldHideStepX = 20;
getPrvBitmap();
break;
case 0:// menu
// 当前置为最新
mCurPageBitmap = mNextPageBitmap;
showMenu=true;
break;
case 1:// next
if (touchLock)
return false;
this.oldX = event.getX();
oldHideStepX = -20;
getNextBitmap();
break;
}
break;
case MotionEvent.ACTION_MOVE:
if(showMenu){break;}
endX = event.getX();
endY = event.getY();
if (Math.abs(endX - touchStartX) > maxX)
maxX = Math.abs(endX - touchStartX);
this.oldX = endX;
//invalidate();
this.doTouchEvent(event);
break;
case MotionEvent.ACTION_UP:
if (showMenu&&mOnShow != null){
mOnShow.onShowBar();
break;
}
this.endX = -1;
this.oldX = event.getX();
if ((event.getX() - touchStartX) < maxX * 2 / 5 && oldHideStepX > 0) {// 取消往右滑动
oldHideStepX = -20;
mNextPageBitmap = mCurPageBitmap;
this.resetCorner();
// 回滚标记点
charStartPos = charStartPosTmp;
charEndPos = charEndPosTmp;
mOnShow.markReadPos(charStartPos);
} else if (oldHideStepX < 0
&& (touchStartX - event.getX()) < maxX * 3 / 5) {// 取消往左滑行
oldHideStepX = 20;
mNextPageBitmap = mCurPageBitmap;
this.resetCorner();
// 回滚标记点
charStartPos = charStartPosTmp;
charEndPos = charEndPosTmp;
mOnShow.markReadPos(charStartPos);
}
maxX = 0;
//invalidate();
this.doTouchEvent(event);
break;
}
return true;
}
@Override
public void getPrvBitmap() {
if(charStartPos <= 0) {//需要加载数据
this.lor=-1;
this.isButtonAction=false;
this.charStartPos=this.charEndPos=0;
mOnShow.getPrvChapter();
mCurPageBitmap = mNextPageBitmap;
return ;
}
charEndPos = charStartPos;
charStartPos = 0;// 上届标记为起始
getLinesToDraw(charStartPos, charEndPos, false);
// 修改real和now的关系
mCurPageBitmap = mNextPageBitmap;
mNextPageBitmap = getBitmap();
}
@Override
public void getNextBitmap() {
if (charEndPos >= this.textCharArr.length - 1) {// 需要加载下一章内容
this.lor=1;
this.isButtonAction=false;
mOnShow.getNextChapter();
mCurPageBitmap = mNextPageBitmap;
return;
}
charStartPos = charEndPos;
charEndPos = this.textCharArr.length - 1;
getLinesToDraw(charStartPos, charEndPos, true);
// 修改real和now的关系
mCurPageBitmap = mNextPageBitmap;
mNextPageBitmap = getBitmap();
if(mCurPageBitmap == null){
mCurPageBitmap = mNextPageBitmap;
}
}
@Override
public void setFontSize(int size) {
fontSize=size;
paint.setTextSize(size);
this.rebuildEnvironment();
paint.getTextWidths(textCharArr, 0, textCharArr.length,textCharArrWidth);
getLinesToDraw(charStartPos, textCharArr.length-1, true);
// 修改now也为当前,及时更新
mNextPageBitmap = getBitmap();
mCurPageBitmap = mNextPageBitmap;
invalidate();
}
@Override
public void setFontColor(int r,int g,int b) {
this.r = r;
this.g = g;
this.b = b;
setTextFrontColor(r, g, b);
// 修改now也为当前,及时更新
mNextPageBitmap = getBitmap();
mCurPageBitmap = mNextPageBitmap;
invalidate();
}
}
Where is HorizontalReadView
去原始博客上下源码看下有木有? 这个我是模仿的,好久不写 Android了 http://download.csdn.net/detail/hmg25/3278901