Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 418|回复: 0

开发交流:Android 翻书 ebook 源码

[复制链接]

该用户从未签到

发表于 2011-10-24 09:38:41 | 显示全部楼层 |阅读模式
package com.newBook;

/*
* Copyright (c) 2010
*
* Author: Wallace Wang
* Email: wallage@qq.com
*/

import java.util.Date;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PorterDuffXfermode;
import android.graphics.Shader;
import android.graphics.PorterDuff.Mode;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.GestureDetector.OnGestureListener;
import android.widget.FrameLayout;
import android.widget.LinearLayout;

public class eBook extends FrameLayout{
public static final String LOG_TAG = "eBook";
int totalPageNum;
Context mContext;
boolean hasInit = false;
final int defaultWidth = 600 , defaultHeight = 400;
int contentWidth = 0;
int contentHeight = 0;
View leftPage,rightPage,llPage,lrPage,rrPage,rlPage;
LinearLayout invisibleView;
LinearLayout mView;
MidView mMidView;
bookView mBookView;
Handler AniEndHandle;
static boolean closeBook = false;

private enum Corner {
  LeftTop,
  RightTop,
  LeftBottom,
  RightBottom,
  None
};
private Corner mSelectCorner;
final int clickCornerLen = 250*250; //50dip
float scrollX = 0,scrollY = 0;
int indexPage = 0;

public enum BookState {
  ABOUT_TO_ANIMATE,
  ANIMATING,
  ANIMATE_END,
  READY,
  TRACKING
};
private BookState mState;
private Point aniStartPos;
private Point aniStopPos;
private Date aniStartTime;
private long aniTime = 800;
private long timeOffset = 10;

Listener mListener;
PageAdapter mPageAdapter;

private GestureDetector mGestureDetector;
private BookOnGestureListener mGestureListener;

public eBook(Context context) {
  super(context);
  Init(context);
}

public eBook(Context context, AttributeSet attrs) {
  super(context, attrs);
  Init(context);
}

public eBook(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  Init(context);
}

public static interface Listener {
  public void onPrevPage();
  public void onNextPage();
  public void onInit();
}

public static interface PageAdapter{
  public View getView(int position);
  public int getCount();
}
public void setListener(Listener listener) {
  Log.d(LOG_TAG,"setListener");
  mListener = listener;
}
public void setPageAdapter(PageAdapter pa){
  Log.d(LOG_TAG,"setPageAdapter");
  mPageAdapter = pa;
}

public void Init(Context context){
  totalPageNum = 0;
  mContext = context;
  
  mSelectCorner = Corner.None;
  
  mGestureListener = new BookOnGestureListener();
  mGestureDetector = new GestureDetector(mGestureListener);
  mGestureDetector.setIsLongpressEnabled(false);
  AniEndHandle = new Handler();
  
  this.setOnTouchListener(touchListener);
  this.setLongClickable(true);
}

public View getLeftPage(){
  return leftPage;
}

public View getRightPage(){
  return rightPage;
}

public View getPrevPage1(){
  return lrPage;
}

public View getPrevPage2(){
  return llPage;
}

public View getNextPage1(){
  return rlPage;
}

public View getNextPage2(){
  return rrPage;
}

public int getIndexForLeftPage(){
  return indexPage;
}

public int getIndexForRightPage(){
  return indexPage + 1;
}

public void setIndexForLeftPage(int index){
  if(index >= 0 && index < totalPageNum){
   if((index % 2) == 0)
    indexPage = index;
   else
    indexPage = index - 1;
  }
}

public void updatePageView(){
  Log.d(LOG_TAG,"updatePageView");
  if(indexPage < 0 || indexPage > totalPageNum - 1){
   Log.d(LOG_TAG,"indexPage exceed bound");
   return;
  }
  invisibleView.removeAllViews();
  mView.removeAllViews();
  
  leftPage = mPageAdapter.getView(indexPage);
  if(leftPage == null)leftPage = new WhiteView(mContext);
  leftPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  mView.addView(leftPage);
  
  lrPage = mPageAdapter.getView(indexPage-1);
  if(lrPage == null)lrPage = new WhiteView(mContext);
  lrPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  invisibleView.addView(lrPage);
  
  llPage = mPageAdapter.getView(indexPage-2);
  if(llPage == null)llPage = new WhiteView(mContext);
  llPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  invisibleView.addView(llPage);
  
  rightPage = mPageAdapter.getView(indexPage+1);
  if(rightPage == null)rightPage = new WhiteView(mContext);
  rightPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  mView.addView(rightPage);
  
  rlPage = mPageAdapter.getView(indexPage+2);
  if(rlPage == null)rlPage = new WhiteView(mContext);
  rlPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  invisibleView.addView(rlPage);
  
  rrPage = mPageAdapter.getView(indexPage+3);
  if(rrPage == null)rrPage = new WhiteView(mContext);
  rrPage.setLayoutParams(new LayoutParams(contentWidth/2,contentHeight));
  invisibleView.addView(rrPage);
  
  Log.d(LOG_TAG,"updatePageView finish");
}

OnTouchListener touchListener = new OnTouchListener() {
  public boolean onTouch(View v, MotionEvent event) {
   Log.d(LOG_TAG, "onTouch " + " x: " + event.getX() + " y: " + event.getY() +
     " mState:" + mState);
   mGestureDetector.onTouchEvent(event);
   int action = event.getAction();
   if (action == MotionEvent.ACTION_UP && mSelectCorner != Corner.None
     && mState == BookState.TRACKING) {
    if(mState == BookState.ANIMATING)return false;
    if(mSelectCorner == Corner.LeftTop || mSelectCorner == Corner.RightTop){
     if(scrollX < contentWidth/2){
      aniStopPos = new Point(0,0);
     }else{
      aniStopPos = new Point(contentWidth,0);
     }
    }else if(mSelectCorner == Corner.LeftBottom || mSelectCorner == Corner.RightBottom){
     if(scrollX < contentWidth/2){
      aniStopPos = new Point(0,contentHeight);
     }else{
      aniStopPos = new Point(contentWidth,contentHeight);
     }
    }
    aniStartPos = new Point((int)scrollX,(int)scrollY);
    aniTime = 800;
    mState = BookState.ABOUT_TO_ANIMATE;
    closeBook = true;
    aniStartTime = new Date();
    mBookView.startAnimation();
   }
   return false;
  }
};

class BookOnGestureListener implements OnGestureListener {
  public boolean onDown(MotionEvent event) {
   Log.d(LOG_TAG, "onDown");
   if(mState == BookState.ANIMATING)return false;
   float x = event.getX(), y = event.getY();
   int w = contentWidth, h = contentHeight;
   if(x*x + y*y < clickCornerLen){
    if(indexPage > 1){
     mSelectCorner = Corner.LeftTop;
     aniStartPos = new Point(0,0);
    }
   }else if((x-w)*(x-w)+ y*y < clickCornerLen){
    if(indexPage < totalPageNum-2){
     mSelectCorner = Corner.RightTop;
     aniStartPos = new Point(contentWidth,0);
    }
   }else if(x*x + (y-h)*(y-h) < clickCornerLen){
    if(indexPage > 1){
     mSelectCorner = Corner.LeftBottom;
     aniStartPos = new Point(0,contentHeight);
    }
   }else if((x-w)*(x-w) + (y-h)*(y-h) < clickCornerLen){
    if(indexPage < totalPageNum-2){
     mSelectCorner = Corner.RightBottom;
     aniStartPos = new Point(contentWidth,contentHeight);
    }
   }
   if(mSelectCorner != Corner.None){
    aniStopPos = new Point((int)x,(int)y);
    aniTime = 800;
    mState = BookState.ABOUT_TO_ANIMATE;
    closeBook = false;
    aniStartTime = new Date();
    mBookView.startAnimation();
   }
   return false;
  }
  
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
   Log.d(LOG_TAG, "onFling velocityX:"+velocityX+" velocityY:"+velocityY);
   if(mSelectCorner != Corner.None){
    if(mSelectCorner == Corner.LeftTop || mSelectCorner == Corner.RightTop){
     if(velocityX < 0){
      aniStopPos = new Point(0,0);
     }else{
      aniStopPos = new Point(contentWidth,0);
     }
    }else if(mSelectCorner == Corner.LeftBottom || mSelectCorner == Corner.RightBottom){
     if(velocityX < 0){
      aniStopPos = new Point(0,contentHeight);
     }else{
      aniStopPos = new Point(contentWidth,contentHeight);
     }
    }
    Log.d(LOG_TAG, "onFling animate");
    aniStartPos = new Point((int)scrollX,(int)scrollY);
    aniTime = 1000;
    mState = BookState.ABOUT_TO_ANIMATE;
    closeBook = true;
    aniStartTime = new Date();
    mBookView.startAnimation();
   }
   return false;
  }

  public void onLongPress(MotionEvent e) {
   Log.d(LOG_TAG, "onLongPress");
  }

  public boolean onScroll(MotionEvent e1, MotionEvent e2,
    float distanceX, float distanceY) {
//   if(mState == BookState.ANIMATING)return false;
   mState = BookState.TRACKING;
   if(mSelectCorner != Corner.None){
    scrollX = e2.getX();
    scrollY = e2.getY();
    mBookView.startAnimation();
   }
   return false;
  }

  public void onShowPress(MotionEvent e) {
   Log.d(LOG_TAG, "onShowPress");
  }

  public boolean onSingleTapUp(MotionEvent e) {
   Log.d(LOG_TAG, "onSingleTapUp");
   if(mSelectCorner != Corner.None){
    if(mSelectCorner == Corner.LeftTop || mSelectCorner == Corner.RightTop){
     if(scrollX < contentWidth/2){
      aniStopPos = new Point(0,0);
     }else{
      aniStopPos = new Point(contentWidth,0);
     }
    }else if(mSelectCorner == Corner.LeftBottom || mSelectCorner == Corner.RightBottom){
     if(scrollX < contentWidth/2){
      aniStopPos = new Point(0,contentHeight);
     }else{
      aniStopPos = new Point(contentWidth,contentHeight);
     }
    }
    aniStartPos = new Point((int)scrollX,(int)scrollY);
    aniTime = 800;
    mState = BookState.ABOUT_TO_ANIMATE;
    closeBook = true;
    aniStartTime = new Date();
    mBookView.startAnimation();
   }
   return false;
  }
}

protected void onFinishInflate() {
  Log.d(LOG_TAG, "onFinishInflate");
  super.onFinishInflate();
}

protected void onLayout(boolean changed, int l, int t, int r, int b) {
  super.onLayout(changed, l, t, r, b);
  
  contentWidth = this.getWidth();
  contentHeight = this.getHeight();
  if(contentWidth == 0) contentWidth = defaultWidth;
  if(contentHeight == 0) contentHeight = defaultHeight;
  Log.d(LOG_TAG, "onLayout, width:" + contentWidth + " height:" + contentHeight);
}

protected void dispatchDraw(Canvas canvas) {
  Log.d(LOG_TAG, "dispatchDraw");
  super.dispatchDraw(canvas);
  if(!hasInit){
   hasInit = true;
   indexPage = 0;
   if(mPageAdapter == null){
    throw new RuntimeException("please set the PageAdapter on init");
   }
   totalPageNum = mPageAdapter.getCount();
   mView = new LinearLayout(mContext);
   mView.setLayoutParams(new LayoutParams(contentWidth,contentHeight));
   mView.setBackgroundColor(0xffffffff);
   mState = BookState.READY;
   
   invisibleView = new LinearLayout(mContext);
   invisibleView.setLayoutParams(new LayoutParams(contentWidth,contentHeight));
   
   mMidView = new MidView(mContext);
   mMidView.setLayoutParams(new LayoutParams(contentWidth,contentHeight));
   
   this.addView(invisibleView);
   this.addView(mView);
   this.addView(mMidView);
   
   mBookView = new bookView(mContext);
   mBookView.setLayoutParams(new LayoutParams(contentWidth,contentHeight));
   this.addView(mBookView);
   
//   invisibleView.setVisibility(INVISIBLE);
//   mBookView.setVisibility(GONE);
   updatePageView();
   invalidate();
   if(mListener != null)mListener.onInit();
  }else if (mState == BookState.READY){
   mBookView.update();
  }
}

class bookView extends SurfaceView implements SurfaceHolder.Callback{
  DrawThread dt; //后台屏幕绘制线程
  SurfaceHolder surfaceHolder;
  Paint mDarkPaint = new Paint();
  Paint mPaint = new Paint();
  Bitmap tmpBmp = Bitmap.createBitmap(contentWidth/2,contentHeight,Bitmap.Config.ARGB_8888);
  Canvas mCanvas = new Canvas(tmpBmp);
  
  Paint bmpPaint = new Paint();
  Paint ivisiblePaint = new Paint();
  
  public bookView(Context context) {
   super(context);
   surfaceHolder = getHolder();
   surfaceHolder.addCallback(this);
   
   mDarkPaint.setColor(0x88000000);
   Shader mLinearGradient = new LinearGradient(0, 0, contentWidth, 0,
     new int[] { 0x00000000, 0x33000000,0x00000000 },
     new float[] { 0.35f, 0.5f, 0.65f },
     Shader.TileMode.MIRROR);
   mPaint.setAntiAlias(true);
   mPaint.setShader(mLinearGradient);
   
   bmpPaint.setFilterBitmap(true);
   bmpPaint.setAntiAlias(true);
   
   ivisiblePaint.setAlpha(0);
   ivisiblePaint.setFilterBitmap(true);
   ivisiblePaint.setAntiAlias(true);
   ivisiblePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
  }
  public void startAnimation(){
//   update();
   if(dt == null){
    Log.d(LOG_TAG,"startAnimation");
//    mBookView.setVisibility(VISIBLE);
    dt = new DrawThread(this,getHolder());
    dt.start();
   }
  }
  
  public void stopAnimation(){
   Log.d(LOG_TAG,"stopAnimation");
//   AniEndHandle.post(new Runnable(){
//    public void run() {
//     mBookView.setVisibility(GONE);
//    }
//   });
   if(dt != null){
    dt.flag = false;
    Thread t = dt;
    dt = null;
    t.interrupt();
   }
  }

  public void drawLT(Canvas canvas){
   double dx = scrollX - contentWidth/2, dy = scrollY;
   double len = Math.sqrt(dx*dx + dy*dy);
   if(len > contentWidth/2){
    scrollX = (float) (contentWidth*dx/(2.0*len)) + contentWidth/2;
    scrollY = (float) (contentWidth*dy/(2.0*len));
   }
   dy = contentHeight - scrollY;
   len = Math.sqrt(dx*dx + dy*dy);
   double d = Math.sqrt(contentWidth*contentWidth/4 + contentHeight*contentHeight);
   if(len > d){
    scrollX = (float) (d*dx/len) + contentWidth/2;
    scrollY = contentHeight - (float) (d*dy/len);
   }
   double px = scrollX;
   double py = scrollY;
   double arc = 2 * Math.atan(py/px)*180/Math.PI;

   Matrix m = new Matrix();
   m.postTranslate(scrollX - contentWidth/2, scrollY);
   m.postRotate((float)(arc),scrollX,scrollY);

   lrPage.draw(mCanvas);

   Paint ps = new Paint();
   Shader lg1 = new LinearGradient(contentWidth/2, 0,
      contentWidth/2 - (float)px,(float)py,
      new int[] { 0x00000000, 0x33000000,0x00000000 },
      new float[] { 0.35f, 0.5f, 0.65f },
      Shader.TileMode.CLAMP);
   ps.setShader(lg1);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   canvas.drawBitmap(tmpBmp, m, bmpPaint);

   llPage.draw(mCanvas);
   Shader lg2 = new LinearGradient(scrollX,scrollY,0, 0,
     new int[] { 0x00000000, 0x33000000,0x00000000 },
     new float[] { 0.35f, 0.5f, 0.65f },
     Shader.TileMode.CLAMP);
   ps.setShader(lg2);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);

   arc = arc*Math.PI/360;
   Path path = new Path();
   double r = Math.sqrt(px * px + py * py);
   double p1 = r/(2*Math.cos(arc));
   double p2 = r/(2*Math.sin(arc));
   Log.d(LOG_TAG,"p1: " + p1 + " p2:" + p2);
   if(arc == 0){
    path.moveTo((float)p1, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo((float)p1, contentHeight);
    path.close();
   }else if(p2 > contentHeight || p2 < 0){
    double p3 = (p2 - contentHeight)*Math.tan(arc);
    path.moveTo((float)p1, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo((float)p3, contentHeight);
    path.close();
   }else{
    path.moveTo((float)p1, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo(0, contentHeight);
    path.lineTo(0, (float)p2);
    path.close();
   }
   mCanvas.drawPath(path, ivisiblePaint);
   canvas.drawBitmap(tmpBmp, 0, 0, null);
  }

  public void drawLB(Canvas canvas){
   double dx = scrollX - contentWidth/2, dy = scrollY - contentHeight;
   double len = Math.sqrt(dx*dx + dy*dy);
   if(len > contentWidth/2){
    scrollX = (float) (contentWidth*dx/(2.0*len)) + contentWidth/2;
    scrollY = (float) (contentWidth*dy/(2.0*len)) + contentHeight;
   }
   dy = scrollY;
   len = Math.sqrt(dx*dx + dy*dy);
   double d = Math.sqrt(contentWidth*contentWidth/4 + contentHeight*contentHeight);
   if(len > d){
    scrollX = (float) (d*dx/len) + contentWidth/2;
    scrollY = (float) (d*dy/len);
   }
   double px = scrollX;
   double py = contentHeight - scrollY;
   double arc = 2 * Math.atan(py/px)*180/Math.PI;
   
   Matrix m = new Matrix();
   m.postTranslate(scrollX - contentWidth/2, scrollY - contentHeight);
   m.postRotate((float)(-arc),scrollX,scrollY);
   
   lrPage.draw(mCanvas);
   
   Paint ps = new Paint();
   Shader lg1 = new LinearGradient(contentWidth/2, contentHeight,
      contentWidth/2 - (float)px, contentHeight - (float)py,
      new int[] { 0x00000000, 0x33000000,0x00000000 },
      new float[] { 0.35f, 0.5f, 0.65f },
      Shader.TileMode.CLAMP);
   ps.setShader(lg1);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   canvas.drawBitmap(tmpBmp, m, bmpPaint);
   
   llPage.draw(mCanvas);
   Shader lg2 = new LinearGradient(scrollX,scrollY,0, contentHeight,
     new int[] { 0x00000000, 0x33000000,0x00000000 },
     new float[] { 0.35f, 0.5f, 0.65f },
     Shader.TileMode.CLAMP);
   ps.setShader(lg2);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   
   arc = arc*Math.PI/360;
   Path path = new Path();
   double r = Math.sqrt(px * px + py * py);
   double p1 = r/(2*Math.cos(arc));
   double p2 = r/(2*Math.sin(arc));
   Log.d(LOG_TAG,"p1: " + p1 + " p2:" + p2);
   if(arc == 0){
    path.moveTo((float)p1, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo((float)p1, contentHeight);
    path.close();
   }else if(p2 > contentHeight || p2 < 0){
    double p3 = (p2 - contentHeight)*Math.tan(arc);
    path.moveTo((float)p3, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo((float)p1, contentHeight);
    path.close();
   }else{
    path.moveTo(0, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo((float)p1, contentHeight);
    path.lineTo(0, contentHeight - (float)p2);
    path.close();
   }
   mCanvas.drawPath(path, ivisiblePaint);
   canvas.drawBitmap(tmpBmp, 0, 0, null);
  }
  
  public void drawRT(Canvas canvas){
   double dx = scrollX - contentWidth/2, dy = scrollY;
   double len = Math.sqrt(dx*dx + dy*dy);
   if(len > contentWidth/2){
    scrollX = (float) (contentWidth*dx/(2.0*len)) + contentWidth/2;
    scrollY = (float) (contentWidth*dy/(2.0*len));
   }
   dy = contentHeight - scrollY;
   len = Math.sqrt(dx*dx + dy*dy);
   double d = Math.sqrt(contentWidth*contentWidth/4 + contentHeight*contentHeight);
   if(len > d){
    scrollX = (float) (d*dx/len) + contentWidth/2;
    scrollY = contentHeight - (float) (d*dy/len);
   }
   double px = contentWidth - scrollX;
   double py = scrollY;
   double arc = 2 * Math.atan(py/px)*180/Math.PI;
   
   Matrix m = new Matrix();
   m.postTranslate(scrollX, scrollY);
   m.postRotate((float)(-arc),scrollX,scrollY);
   
   rlPage.draw(mCanvas);
   
   Paint ps = new Paint();
   Shader lg1 = new LinearGradient(0, 0, (float)px, (float)py,
      new int[] { 0x00000000, 0x33000000,0x00000000 },
      new float[] { 0.35f, 0.5f, 0.65f },
      Shader.TileMode.CLAMP);
   ps.setShader(lg1);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   canvas.drawBitmap(tmpBmp, m, bmpPaint);
   
   rrPage.draw(mCanvas);
   Shader lg2 = new LinearGradient(scrollX-contentWidth/2, scrollY,
     contentWidth/2, 0,
     new int[] { 0x00000000, 0x33000000,0x00000000 },
     new float[] { 0.35f, 0.5f, 0.65f },
     Shader.TileMode.CLAMP);
   ps.setShader(lg2);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   
   arc = arc*Math.PI/360;
   Path path = new Path();
   double r = Math.sqrt(px * px + py * py);
   double p1 = contentWidth/2 - r/(2*Math.cos(arc));
   double p2 = r/(2*Math.sin(arc));
   Log.d(LOG_TAG,"p1: " + p1 + " p2:" + p2);
   if(arc == 0){
    path.moveTo(0, 0);
    path.lineTo((float)p1, 0);
    path.lineTo((float)p1, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }else if(p2 > contentHeight || p2 < 0){
    double p3 = contentWidth/2 - (p2 - contentHeight)*Math.tan(arc);
    path.moveTo(0, 0);
    path.lineTo((float)p1, 0);
    path.lineTo((float)p3, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }else{
    path.moveTo(0, 0);
    path.lineTo((float)p1, 0);
    path.lineTo(contentWidth/2, (float)p2);
    path.lineTo(contentWidth/2, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }
   mCanvas.drawPath(path, ivisiblePaint);
   canvas.drawBitmap(tmpBmp, contentWidth/2, 0, null);
  }
  
  public void drawRB(Canvas canvas){
   double dx = scrollX - contentWidth/2, dy = contentHeight - scrollY;
   double len = Math.sqrt(dx*dx + dy*dy);
   if(len > contentWidth/2){
    scrollX = (float) (contentWidth*dx/(2.0*len)) + contentWidth/2;
    scrollY = contentHeight - (float) (contentWidth*dy/(2.0*len));
   }
   dy = scrollY;
   len = Math.sqrt(dx*dx + dy*dy);
   double d = Math.sqrt(contentWidth*contentWidth/4 + contentHeight*contentHeight);
   if(len > d){
    scrollX = (float) (d*dx/len) + contentWidth/2;
    scrollY = (float) (d*dy/len);
   }
   double px = contentWidth - scrollX;
   double py = contentHeight - scrollY;
   double arc = 2 * Math.atan(py/px)*180/Math.PI;
   
   Matrix m = new Matrix();
   m.postTranslate(scrollX, scrollY - contentHeight);
   m.postRotate((float)(arc),scrollX,scrollY);
   
   rlPage.draw(mCanvas);
   
   Paint ps = new Paint();
   Shader lg1 = new LinearGradient(0, contentHeight,
      (float)px,contentHeight-(float)py,
      new int[] { 0x00000000, 0x33000000,0x00000000 },
      new float[] { 0.35f, 0.5f, 0.65f },
      Shader.TileMode.CLAMP);
   ps.setShader(lg1);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   canvas.drawBitmap(tmpBmp, m, bmpPaint);
   
   rrPage.draw(mCanvas);
   Shader lg2 = new LinearGradient(scrollX-contentWidth/2, scrollY,
     contentWidth/2, contentHeight,
     new int[] { 0x00000000, 0x33000000,0x00000000 },
     new float[] { 0.35f, 0.5f, 0.65f },
     Shader.TileMode.CLAMP);
   ps.setShader(lg2);
   mCanvas.drawRect(0, 0, contentWidth/2, contentHeight, ps);
   
   arc = arc*Math.PI/360;
   Path path = new Path();
   double r = Math.sqrt(px * px + py * py);
   double p1 = contentWidth/2 - r/(2*Math.cos(arc));
   double p2 = r/(2*Math.sin(arc));
   Log.d(LOG_TAG,"p1: " + p1 + " p2:" + p2);
   if(arc == 0){
    path.moveTo(0, 0);
    path.lineTo((float)p1, 0);
    path.lineTo((float)p1, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }else if(p2 > contentHeight || p2 < 0){
    double p3 = contentWidth/2 - (p2 - contentHeight)*Math.tan(arc);
    path.moveTo(0, 0);
    path.lineTo((float)p3, 0);
    path.lineTo((float)p1, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }else{
    path.moveTo(0, 0);
    path.lineTo(contentWidth/2, 0);
    path.lineTo(contentWidth/2, contentHeight - (float)p2);
    path.lineTo((float)p1, contentHeight);
    path.lineTo(0, contentHeight);
    path.close();
   }
   mCanvas.drawPath(path, ivisiblePaint);
   canvas.drawBitmap(tmpBmp, contentWidth/2, 0, null);
  }
  
  public void drawPrevPageEnd(Canvas canvas){
   llPage.draw(mCanvas);
   canvas.drawBitmap(tmpBmp, 0, 0, null);
   lrPage.draw(mCanvas);
   canvas.drawBitmap(tmpBmp, contentWidth/2, 0, null);
   
   canvas.drawRect(0, 0, contentWidth, contentHeight, mPaint);
   canvas.drawLine(contentWidth/2, 0, contentWidth/2, contentHeight, mDarkPaint);
  }
  
  public void drawNextPageEnd(Canvas canvas) {
   rlPage.draw(mCanvas);
   canvas.drawBitmap(tmpBmp, 0, 0, null);
   rrPage.draw(mCanvas);
   canvas.drawBitmap(tmpBmp, contentWidth / 2, 0, null);

   canvas.drawRect(0, 0, contentWidth, contentHeight, mPaint);
   canvas.drawLine(contentWidth/2, 0, contentWidth/2, contentHeight, mDarkPaint);
  }
  
  public void drawPage(Canvas canvas){
   if(mSelectCorner == Corner.LeftTop){
    Log.d(LOG_TAG,"click left top");
    drawLT(canvas);
   }else if(mSelectCorner == Corner.LeftBottom){
    Log.d(LOG_TAG,"click left bottom");
    drawLB(canvas);
   }else if(mSelectCorner == Corner.RightTop){
    Log.d(LOG_TAG,"click right top");
    drawRT(canvas);
   }else if(mSelectCorner == Corner.RightBottom){
    Log.d(LOG_TAG,"click right bottom");
    drawRB(canvas);
   }
  }
  
  public void update(){
   Canvas canvas = surfaceHolder.lockCanvas(null);//获取BallView的画布
   try{
    synchronized(surfaceHolder){
     doDraw(canvas);  //调用BallView的doDraw方法进行绘制
    }
   }
   catch(Exception e){
    e.printStackTrace();   //捕获并打印异常
   }
   finally{
    if(canvas != null){  //如果canvas不为空
     surfaceHolder.unlockCanvasAndPost(canvas);//surfaceHolder解锁并将画布对象传回
    }
   }
  }
  
  protected void doDraw(Canvas canvas) {
   Log.d(LOG_TAG, "bookView doDraw");
//   super.onDraw(canvas);
   mView.draw(canvas);
   
   canvas.drawRect(0, 0, contentWidth, contentHeight, mPaint);
   canvas.drawLine(contentWidth/2, 0, contentWidth/2, contentHeight, mDarkPaint);
  }

  public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
   
  }

  public void surfaceCreated(SurfaceHolder holder) {
   update();
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
   if(dt != null){
    dt.flag = false; //停止线程的执行
    dt = null;   //将dt指向的对象声明为垃圾
   }
  }
}

public boolean getAnimateData(){
  long time = aniTime;
  Date date = new Date();
  long t = date.getTime()-aniStartTime.getTime();
  t += timeOffset;
  if(t < 0 || t > time){
   mState = BookState.ANIMATE_END;
   return false;
  }else{
   mState = BookState.ANIMATING;
   double sx = aniStopPos.x - aniStartPos.x;
   double gx = 2*sx/(time*time);
   scrollX = (float) (gx*time*t - gx*t*t/2 + aniStartPos.x);
   double sy = aniStopPos.y - aniStartPos.y;
   double gy = 2*sy/(time*time);
   scrollY = (float) (gy*time*t - gy*t*t/2 + aniStartPos.y);
   return true;
  }
}

public void handleAniEnd(Canvas canvas){
  if(closeBook){
   closeBook = false;
   if(mSelectCorner == Corner.LeftTop || mSelectCorner == Corner.LeftBottom){
    if(scrollX > contentWidth/2){
     Log.d(LOG_TAG,"handleAniEnd -2,indexPage:"+ (indexPage-2));
     indexPage -= 2;
     mBookView.drawPrevPageEnd(canvas);
     AniEndHandle.post(new Runnable(){
      public void run() {
       updatePageView();
       if(mListener != null){
        Log.d(LOG_TAG,"onPrevPage");
        mListener.onPrevPage();
       }
      }
     });
    }else{
     mBookView.doDraw(canvas);
    }
   }else if(mSelectCorner == Corner.RightTop || mSelectCorner == Corner.RightBottom){
    if(scrollX < contentWidth/2){
     Log.d(LOG_TAG,"handleAniEnd +2,indexPage:"+ (indexPage+2));
     indexPage += 2;
     mBookView.drawNextPageEnd(canvas);
     AniEndHandle.post(new Runnable(){
      public void run() {
       updatePageView();
       if(mListener != null){
        Log.d(LOG_TAG,"onNextPage");
        mListener.onNextPage();
       }
      }
     });
    }else{
     mBookView.doDraw(canvas);
    }
   }
   mSelectCorner = Corner.None;
   mState = BookState.READY;
  }else{
   mState = BookState.TRACKING;
  }
  mBookView.stopAnimation();
  AniEndHandle.post(new Runnable(){
   public void run() {
    eBook.this.invalidate();
   }
  });
}

class WhiteView extends View{
  public WhiteView(Context context) {
   super(context);
  }
  
  protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
   canvas.drawColor(Color.WHITE);
  }
}

class MidView extends View{
  public MidView(Context context) {
   super(context);
  }
  
  protected void onDraw(Canvas canvas) {
   super.onDraw(canvas);
   Paint mPaint = new Paint();
   Shader mLinearGradient = new LinearGradient(0, 0, contentWidth, 0,
      new int[] { 0x00000000, 0x33000000,0x00000000 },
      new float[] { 0.35f, 0.5f, 0.65f },
      Shader.TileMode.MIRROR);
   mPaint.setAntiAlias(true);
   mPaint.setShader(mLinearGradient);
   canvas.drawRect(0, 0, contentWidth, contentHeight, mPaint);
   
   Paint mDarkPaint = new Paint();
   mDarkPaint.setColor(0x88000000);
   canvas.drawLine(contentWidth/2, 0, contentWidth/2, contentHeight, mDarkPaint);
  }
}

public class DrawThread extends Thread{
  bookView bv;    //bookView对象引用
  SurfaceHolder surfaceHolder;//SurfaceHolder对象引用
  boolean flag=false;   //线程执行标志位
  int sleepSpan = 30;   //休眠时间
  public DrawThread(bookView bv,SurfaceHolder surfaceHolder){
   this.bv = bv;  //为BallView对象应用赋值
   this.surfaceHolder = surfaceHolder; //为SurfaceHolder对象应用赋值
   this.flag = true;  //设置标志位
  }
  
  public void run(){
   Canvas canvas = null;//声明一个Canvas对象
   while(flag){
    try{
     canvas = surfaceHolder.lockCanvas(null);//获取BallView的画布
     if(canvas == null)continue;
     synchronized(surfaceHolder){
      if(mState == BookState.ABOUT_TO_ANIMATE || mState == BookState.ANIMATING){
       bv.doDraw(canvas);  //调用BallView的doDraw方法进行绘制
       getAnimateData();
       bv.drawPage(canvas);
      }else if(mState == BookState.TRACKING){
       bv.doDraw(canvas);
       bv.drawPage(canvas);
      }else if(mState == BookState.ANIMATE_END){
       handleAniEnd(canvas);
      }
     }
    }
    catch(Exception e){
     e.printStackTrace();   //捕获并打印异常
    }
    finally{
     if(canvas != null){  //如果canvas不为空
      surfaceHolder.unlockCanvasAndPost(canvas);//surfaceHolder解锁并将画布对象传回
     }
    }
    try{
     Thread.sleep(sleepSpan);  //线程休眠一段时间
    }
    catch(Exception e){
     e.printStackTrace();  //捕获并打印异常
    }
   }
  }
}
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

GMT+8, 2025-1-10 23:16 , Processed in 0.302895 second(s), 36 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表