2019独角兽企业重金招聘Python工程师标准>>>

模仿此效果,只需要 导入一下文件即可 :BookActivity.java,BookPageFactory.java,PageWidget.java

package com.andorid.shu.love;import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Toast;import com.sqlite.DbHelper;public class BookActivity extends Activity {/** Called when the activity is first created. */public final static int OPENMARK = 0;public final static int SAVEMARK = 1;public final static int TEXTSET = 2;private PageWidget mPageWidget;private Bitmap mCurPageBitmap, mNextPageBitmap;private Canvas mCurPageCanvas, mNextPageCanvas;private BookPageFactory pagefactory;private static Boolean isExit = false;//用于判断是否推出private static Boolean hasTask = false;private int whichSize=6;//当前的字体大小private int txtProgress = 0;//当前阅读的进度private String txtPath = "/sdcard/lovereader/百年孤独.txt";private String bookPath = "/sdcard/lovereader/";final String[] font = new String[] {"20","24","26","30","32","36","40","46","50","56","60","66","70"};int curPostion;DbHelper db; Context mContext;Cursor mCursor;BookInfo book = null; SetupInfo setup = null;//add for 2015-03-04private int[] mPics = new int [] {R.drawable.c0,R.drawable.c1,R.drawable.c2,R.drawable.c3};private int mCurrent = 0;private int mNext = 1;//add for 2015-03-06private List<String> mFileList = new ArrayList<String>();private static final String TAG = "BookActivity";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);/*requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);*/Display display = getWindowManager().getDefaultDisplay();int w = display.getWidth();int h = display.getHeight(); System.out.println(w + "\t" + h);BitmapFactory.Options options = new BitmapFactory.Options();  options.inSampleSize = 2;//图片大小,设置越大,图片越不清晰,占用空间越小 /*String SDPath = getSDPath();Log.d(TAG, "sdPath:"+SDPath);*////getFile(new File("/storage/extSdCard/pic/pic_1"));//get FileDirPathString dirPath = getIntent().getStringExtra("....");dirPath = "/storage/extSdCard/pic/pic_1";File mFile = new File(dirPath);if(mFile.exists()){if(mFile.isDirectory()){if(mFile.listFiles().length==0){Toast.makeText(this, "文件不存在!", Toast.LENGTH_SHORT).show();return;}}}try {//获取文件夹下的所有图片路径 填充mFileList集合getFile(mFile);} catch (IOException e2) {// TODO Auto-generated catch blocke2.printStackTrace();}pagefactory = new BookPageFactory(w, h,mFileList);mCurPageBitmap = BitmapFactory.decodeFile(mFileList.get(mCurrent), options);mNextPageBitmap = BitmapFactory.decodeFile(mFileList.get(mNext), options);mCurPageBitmap = pagefactory.resizePic(mCurPageBitmap, w, h);mNextPageBitmap = pagefactory.resizePic(mNextPageBitmap, w, h);mContext = this;mPageWidget = new PageWidget(this, w, h);setContentView(mPageWidget);mPageWidget.setBitmaps(mCurPageBitmap, mNextPageBitmap);mPageWidget.setOnTouchListener(new OnTouchListener() {@Overridepublic boolean onTouch(View v, MotionEvent e) {boolean ret = false;if (v == mPageWidget) {if (e.getAction() == MotionEvent.ACTION_DOWN) {mPageWidget.abortAnimation();mPageWidget.calcCornerXY(e.getX(), e.getY());//int temp = mCurrent!=0?mCurrent-1:0;//获取当前页mCurPageBitmap = pagefactory.getPage(mCurrent);Log.d(TAG, "---当前页:mCurrentPic:"+mCurrent);Log.d(TAG, "---当前页:路径:"+mFileList.get(mCurrent));if (mPageWidget.DragToRight()) {if (pagefactory.isfirstPage()){Toast.makeText(mContext, "已经是第一页",Toast.LENGTH_SHORT).show(); return false;}//获取当前页坐标mCurrent = mCurrent > 0?--mCurrent:0;Log.d(TAG, "mCurrentPic:"+mCurrent);mNextPageBitmap = pagefactory.prePage(mCurrent);Log.d(TAG, "---下一页:路径:"+mFileList.get(mCurrent));} else {if (pagefactory.islastPage()){Toast.makeText(mContext, "已经是最后一页",Toast.LENGTH_SHORT).show();return false;}mCurrent = mCurrent < mFileList.size()-1 ?++mCurrent:mFileList.size()-1;Log.d(TAG, "mCurrentPic:"+mCurrent);Log.d(TAG, "---下一页:路径:"+mFileList.get(mCurrent));mNextPageBitmap = pagefactory.nextPage(mCurrent);}mPageWidget.setBitmaps(mCurPageBitmap, mNextPageBitmap);}ret = mPageWidget.doTouchEvent(e);return ret;}return false;}});}public String getSDPath(){ File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);   //判断sd卡是否存在 if(sdCardExist){                               sdDir = Environment.getExternalStorageDirectory();//获取跟目录 }return sdDir.toString();       }/*** 获取文件对象* @param file* @return* @throws IOException */public List<String> getFile(File file) throws IOException{
//      Log.d(TAG, "getFile.fun..start..");File[] fileArray =file.listFiles();
//      Log.d(TAG, "getFile.fun..listFiles..");for (File f : fileArray) {
//          Log.d(TAG, "getFile.fun..ffff..");if(f.isFile()){
//              Log.d(TAG, "getFile.fun..adddd..11111..");mFileList.add(f.getCanonicalPath());
//              Log.d(TAG, "getFile.fun..adddd..");}else{getFile(f);
//              Log.d(TAG, "getFile.run..again..");}}
//      Log.d(TAG, "getFile.fun..finsh..");return mFileList;}
}

修改 BookActivity.java dirPath 路径即可

BookPageFactory.java

package com.andorid.shu.love;import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Vector;import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Align;public class BookPageFactory {private File book_file = null;private MappedByteBuffer m_mbBuf = null;private int m_mbBufLen = 0;private int m_mbBufBegin = 50; //50private int m_mbBufEnd = 0;private String m_strCharsetName = "GBK";private Bitmap m_book_bg = null;private int mWidth;private int mHeight;private Vector<String> m_lines = new Vector<String>();private int m_fontSize = 40;private int r_fontSize = 30;private int m_textColor = Color.BLACK;private int m_backColor = 0xffff9e85; // 背景颜色private int marginWidth = 15; // 左右与边缘的距离private int marginHeight = 20; // 上下与边缘的距离private int youmiHeight = 0;//广告条的狂度private int mLineCount; // 每页可以显示的行数private float mVisibleHeight; // 绘制内容的宽private float mVisibleWidth; // 绘制内容的宽private boolean m_isfirstPage, m_islastPage;private int b_FontSize = 16;//底部文字大小private int e_fontSize = 5;private int spaceSize = 20;//行间距大小private int curProgress = 0;//当前的进度private String fileName = "";// private int m_nLineSpaceing = 5;private Paint mPaint;private Paint bPaint;//底部文字绘制private Paint spactPaint;//行间距绘制private Paint titlePaint;//标题绘制//add for 2015 03 06private List<String> mFileList;//当前文件列表public BookPageFactory(int w, int h,List<String> fileList) {// TODO Auto-generated constructor stubmWidth = w;mHeight = h;//add for 2015 03 04this.mFileList = fileList;}//add for 2015 03 04public Bitmap prePage(int currentNum){this.m_islastPage = false;if(currentNum == 0){//currentNum = 0;this.m_isfirstPage = true;}else{//currentNum--;this.m_isfirstPage = false;}BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;//图片大小,设置越大,图片越不清晰,占用空间越小Bitmap bitmap = BitmapFactory.decodeFile(mFileList.get(currentNum), options);//Bitmap bitmap = BitmapFactory.decodeResource(this.mResources, mPics[currentNum]);//图片放大至屏幕大小bitmap = resizePic(bitmap, mWidth, mHeight);return bitmap;}//add for 2015 03 04public Bitmap nextPage(int currentNum){this.m_isfirstPage = false;if(currentNum >= mFileList.size()-1){//currentNum = mPics.length-1;this.m_islastPage = true;}else{//currentNum++;this.m_islastPage = false;}BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;//图片大小,设置越大,图片越不清晰,占用空间越小Bitmap bitmap = BitmapFactory.decodeFile(mFileList.get(currentNum), options);//Bitmap bitmap = BitmapFactory.decodeResource(this.mResources, mPics[currentNum]);//图片放大至屏幕大小bitmap = resizePic(bitmap, mWidth, mHeight);return bitmap;}//add for 2015 03 06public Bitmap getPage(int currnet){BitmapFactory.Options options = new BitmapFactory.Options();options.inSampleSize = 2;//图片大小,设置越大,图片越不清晰,占用空间越小Bitmap bitmap = BitmapFactory.decodeFile(mFileList.get(currnet), options);//Bitmap bitmap = BitmapFactory.decodeResource(this.mResources, mPics[currnet]);//图片放大至屏幕大小bitmap = resizePic(bitmap, mWidth, mHeight);return bitmap;}//add for 2015 03 06public static Bitmap resizePic(Bitmap bitmap, int screenWidth,int screenHight) {int w = bitmap.getWidth();int h = bitmap.getHeight();Matrix matrix = new Matrix();float scale = (float) screenWidth / w;float scale2 = (float) screenHight / h;// scale = scale < scale2 ? scale : scale2;matrix.postScale(scale, scale2);Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);if (bitmap != null && !bitmap.equals(bmp) && !bitmap.isRecycled()) {bitmap.recycle();bitmap = null;}return bmp;}private static double round1(double v, int scale) {if (scale < 0)return v;String temp = "#####0.";for (int i = 0; i < scale; i++) {temp += "0";}return Double.valueOf(new java.text.DecimalFormat(temp).format(v));}public void setBgBitmap(Bitmap BG) {if (BG.getWidth() != mWidth || BG.getHeight() != mHeight)m_book_bg = Bitmap.createScaledBitmap(BG, mWidth, mHeight, true);elsem_book_bg = BG;}public boolean isfirstPage() {return m_isfirstPage;}public void setIslastPage(boolean islast){m_islastPage = islast;}public boolean islastPage() {return m_islastPage;} public int getCurPostion() {return m_mbBufEnd;}public int getCurPostionBeg(){return m_mbBufBegin;}public void setBeginPos(int pos) {m_mbBufEnd = pos;m_mbBufBegin = pos;}public int getBufLen() {return m_mbBufLen;}public int getCurProgress(){return curProgress;}public String getOneLine() {return m_lines.toString().substring(0, 10);}public void changBackGround(int color) {mPaint.setColor(color);}public void setFontSize(int size) {m_fontSize = size;mPaint.setTextSize(size);int totalSize = m_fontSize+spaceSize;mLineCount = (int) (mVisibleHeight / totalSize); // 可显示的行数}public void setFileName(String fileName){fileName = fileName.substring(0,fileName.indexOf("."));this.fileName = fileName; }}

PageWidget.java

package com.andorid.shu.love;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 PageWidget extends View {private static final String TAG = "hmg";private int mWidth = 480;private int mHeight = 800;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 PageWidget(Context context, int w, int h) {super(context);// TODO Auto-generated constructor stubmWidth = w;mHeight = h;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;}/*** Author : hmg25 Version: 1.0 Description : 计算拖拽点对应的拖拽脚*/public void calcCornerXY(float x, float y) {if (x <= mWidth / 2)mCornerX = 0;elsemCornerX = mWidth;if (y <= mHeight / 2)mCornerY = 0;elsemCornerY = mHeight;if ((mCornerX == 0 && mCornerY == mHeight)|| (mCornerX == mWidth && mCornerY == 0))mIsRTandLB = true;elsemIsRTandLB = false;}public boolean doTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif (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;}/*** Author : hmg25 Version: 1.0 Description : 求解直线P1P2和直线P3P4的交点坐标*/public PointF getCross(PointF P1, PointF P2, PointF P3, PointF P4) {PointF CrossP = new PointF();// 二元函数通式: y=ax+bfloat 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);// Log.i("hmg", "mTouchX  " + mTouch.x + "  mTouchY  " + mTouch.y);// Log.i("hmg", "mBezierControl1.x  " + mBezierControl1.x// + "  mBezierControl1.y  " + mBezierControl1.y);// Log.i("hmg", "mBezierControl2.x  " + mBezierControl2.x// + "  mBezierControl2.y  " + mBezierControl2.y);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);// Log.i("hmg", "mTouchX --> " + mTouch.x + "  mTouchY-->  "// + mTouch.y);// Log.i("hmg", "mBezierControl1.x--  " + mBezierControl1.x// + "  mBezierControl1.y -- " + mBezierControl1.y);// Log.i("hmg", "mBezierControl2.x -- " + mBezierControl2.x// + "  mBezierControl2.y -- " + mBezierControl2.y);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);// Log.i("hmg", "mBezierEnd1.x  " + mBezierEnd1.x + "  mBezierEnd1.y  "// + mBezierEnd1.y);// Log.i("hmg", "mBezierEnd2.x  " + mBezierEnd2.x + "  mBezierEnd2.y  "// + mBezierEnd2.y);/** 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;}@Overrideprotected void onDraw(Canvas canvas) {canvas.drawColor(0xFFAAAAAA);calcPoints();drawCurrentPageArea(canvas, mCurPageBitmap, mPath0);drawNextPageAreaAndShadow(canvas, mNextPageBitmap);drawCurrentPageShadow(canvas);drawCurrentBackArea(canvas, mCurPageBitmap);}/*** Author : hmg25 Version: 1.0 Description : 创建阴影的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);}/*** Author : hmg25 Version: 1.0 Description : 绘制翻起页的阴影*/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;elsetemp = 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);elsemCurrentPageShadow.setBounds((int) (mBezierControl2.x - mMaxLength), leftx,(int) (mBezierControl2.x), rightx);// Log.i("hmg", "mBezierControl2.x   " + mBezierControl2.x// + "  mBezierControl2.y  " + mBezierControl2.y);mCurrentPageShadow.draw(canvas);canvas.restore();}/*** Author : hmg25 Version: 1.0 Description : 绘制翻起页背面*/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;}/*** Author : hmg25 Version: 1.0 Description : 是否从左边翻向右边*/public boolean DragToRight() {if (mCornerX > 0)return false;return true;}}

源代码下载地址

转载于:https://my.oschina.net/u/1866821/blog/383481

Android书籍翻页效果需要用到的文件相关推荐

  1. Android 实现书籍翻页效果----升级篇

    自从之前发布了<Android 实现书籍翻页效果----完结篇 >之后,收到了很多朋友给我留言,前段时间由于事情较多,博客写得太匆忙很多细节地方没有描述清楚.所以不少人对其中的地方有不少不 ...

  2. Android 实现书籍翻页效果----原理篇

    之前看到像ipad上的ibook的模拟书籍翻页的特效感觉很炫,在android上也有像laputa和ireader等应用实现有这个特效,在网上搜索了一下好像也没有现成的例子,所以自己动手实现了一个,现 ...

  3. Android 实现书籍翻页效果---番外篇之光影效果

    By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 对于之前发布的翻页效果的源码,由于写得太匆忙,注释讲解的不多,且本人文笔较差,至使很多人对其中的很多部分不是很清楚 ...

  4. Android 实现书籍翻页效果----完结篇

    By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前由于种种琐事,暂停了这个翻页效果的实现,终于在这周末完成了大部分功能,但是这里只是给出了一个基本的雏形,没有添 ...

  5. Android电子书翻页效果实现

    http://blog.csdn.net/johnsonblog/article/details/7974312 效果 其中使用了贝赛尔曲线原理,关于贝赛尔曲线的知识,推荐大家看下http://blo ...

  6. Android电子书翻页效果

    效果如图: 思路:计算出出各个顶点作为path路径连接 如图 设屏幕右下角为原点O (view宽,view高),e为手指触摸屏幕的坐标,我们先算出点f1与f2的坐标 此处em代表两个点的线段距离,下文 ...

  7. unity 制作书本 翻页效果

    unity 制作书籍翻页效果 unity C# 翻书效果 2D 真实翻页 不使用插件 自制 实现思路: 将书本分为两边,一边一个翻页实现: 下图为书本的右面,以OA为分界线,△OAB是下一面的如上图的 ...

  8. Android开发笔记(十八)书籍翻页动画PageAnimation

    前面几节的动画都算简单,本文就介绍一个复杂点的动画--书籍翻页动画.Android有自带的翻页动画ViewPager,不过ViewPager只实现了平移效果.即便使用补间组合动画或者属性动画,也只是把 ...

  9. Android之实现上下左右翻页效果

    如果实现上下或者左右翻页效果,我们借助下这个开源项目:https://github.com/openaphid/android-flip Aphid FlipView是一个能够实现Flipboard翻 ...

  10. android 仿真翻页动画,Android 两Activity之间动画效果(1)---------翻页效果

    用Android rotate动画实现翻页效果,效果如图: 要实现上面动画,首先搞明白rotate动画原理: (1)Degrees坐标: 0度(360度) 270度 90度  顺时针旋转 180 (2 ...

最新文章

  1. Django 模型查询2.3
  2. Fastq-dump:我的日常命令
  3. JSP知识点笔记-常用技术方法
  4. java流与文件——流
  5. 订阅号微信公众号历史文章爬虫php,一步步教你怎么打造微信公众号历史文章爬虫...
  6. 5、Flutter 实现 ViewPager、bottomNavigationBar 界面切换
  7. Dockerfile 文件结构、docker镜像构建过程详细介绍
  8. 灵格斯(lingoes)去广告方法
  9. Android FrameWork——Binder机制详解(1)
  10. AppFuse项目笔记(1)
  11. 如何阻止EditText专注于Android中的Activity启动
  12. java程序结构化设计_项目二:基于Java的结构化程序设计
  13. Redis实现MongoDB的getlasterror功能
  14. 计算机毕业生学士服,特殊毕业季,这些“别人家的高校”为毕业生送上定制版学士服...
  15. 大话企业IT安全解决方案
  16. 威廉玛丽大学计算机本科专业,威廉玛丽学院本科专业有哪些?
  17. 使用jemdoc制作个人主页
  18. 2012系统架构设计师考试大纲
  19. Unity-如何隐藏App入口,然后通过其他App打开
  20. 将本地的项目导入到github仓库总结lxw

热门文章

  1. 关于css3的背景切割(background-clip)、背景原点(background-origin)的使用
  2. emacs,objective-c mode 代码补全!
  3. 防护针对SQL Server数据库的SQL注入攻击
  4. 顶点计划 班委问题讨论
  5. Getting started with Processing 第七章总结
  6. 《mysql必知必会》学习_第八章_20180730_欢
  7. 04_数字的处理方法(保留小数点两位、将数字转化为千分位格式)
  8. 关于有偿提供拼图响应式后台的通知.
  9. Android滑动页面返回(自定义控件)
  10. javascript变量说明