Open Yhzhtk opened 9 years ago
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