当前位置: 代码迷 >> Android >> android 翻页卷曲成效 电子书翻页
  详细解决方案

android 翻页卷曲成效 电子书翻页

热度:74   发布时间:2016-05-01 17:16:20.0
android 翻页卷曲效果 电子书翻页

转载请注明来自:?5进制空间-android区

相信做电子书的同学,都遇到过翻页动画的需求吧,如果你不满足与点击滑动翻页的话,这边文章应该能够帮助到你。


先上个效果图:






效果还是很不错的,不过与ibook那个效果比起来,还是有差距的。应为这个没用到openGL做3D效果,只是用的2d的canvas画布去画的view,添加了阴影效果,还是挺有立体感的。而且比较流畅。openGL实现肯定效果会更好,不过就我目前的技术实力,实现希望还是渺茫的。

废话少说,还是上代码吧:

这里需要两个UI的view类和一个使用方法的demo。
第一个pageTurnerView.java:

public class PageTurnerViewP1 extends RelativeLayout{ 	  private static final int CORNER_RIGHT_MASK = 1;	  private static final int CORNER_TOP_MASK = 2;	  public static final int CORNER_BOTTOM_LEFT = 0;	  public static final int CORNER_BOTTOM_RIGHT = 1;	  public static final int CORNER_TOP_LEFT = 2;	  public static final int CORNER_TOP_RIGHT = 3;	  private static final int INVALIDATE = 1;	  private static final int INITIAL_TIME_DELAY = 100;	  private static final int TIME_DELAY = 10;//	  private static final int TIME_STEPS = 30;	  private boolean mPageTurning;	  private boolean mStepping;	  public long mNextTime;	  private int mTimeStep;	  private int mDrawnTimeStep;	  private int mCorner;	  private Drawable mBackPage;	  private Drawable mPageBackground;	  private Path mForegroundPath;	  private Path mBackPagePath;	  private Path mBackgroundPath;	  private float mRotation;	  private Rect mChildRect = new Rect();	  private int mOuterOffsetX;	  private int mOuterOffsetY;	  public float mPivotX;	  private int mPageId;	  private PageViewP1 mPage;	  private PointF mPageTurnCorner = new PointF();	  private PointF mOppositeCorner = new PointF();	  private PointF mPageDim = new PointF();	  private int mStepLen = 1;	  public static final int KEEP = 0;	  public static final int NEXT = 1;	  public static final int LAST = 2;	  public int mWhere = KEEP;	  public boolean isBgInit = true;	  public boolean isBackInit = true;	  private  float ax,ay,bx,by,cx,cy,dx,dy,ex,ey,c0x,c0y;	  private int mMaxStep=30;	  public final Handler mHandler = new Handler() {		  public void handleMessage(Message msg) {			  if (msg.what != 1) { return; }//			  PageTurnerViewP1.this.invalidate();			  refreshUI();//			  PageTurnerViewP1.this.invalidate((int)bx, (int)ay, (int)dx, (int)dy);			  if (PageTurnerViewP1.this.mStepping) { return; }			  msg = obtainMessage(1);			  long current = SystemClock.uptimeMillis();			  if (PageTurnerViewP1.this.mNextTime < current) { 				  //PageTurnerViewP1.access$102(PageTurnerViewP1.this, current + 10L); 				 PageTurnerViewP1.this.mNextTime= current + 5L; 			  } 			  sendMessageAtTime(msg, PageTurnerViewP1.this.mNextTime); 			  //PageTurnerViewP1.access$114(PageTurnerViewP1.this, 10L); 				PageTurnerViewP1.this.mNextTime+= 5L; 		  } 	  }; 	 	  public PageTurnerViewP1(Context context) { 		  super(context); 		  Log.i("==================== PageTurnerViewP1(Context context) =================", "" + this); 	  } 	  public PageTurnerViewP1(Context context, AttributeSet attrs) { 		  super(context, attrs); 			 		  this.mPageId = -1; 			this.mCorner = -1; 	  } 	  protected void onFinishInflate() { 		  super.onFinishInflate(); 		  if (this.mPageId != -1) { 			  this.mPage = ((PageViewP1)findViewById(this.mPageId)); 			  if (this.mPage != null) 				  this.mPage.setPageTurner(this); 		  } 	  } 	  public void setPageId(int pageId) { 		  this.mPageId = pageId; 		  this.mPage = ((PageViewP1)findViewById(this.mPageId)); 		  if (this.mPage != null) 			  this.mPage.setPageTurner(this); 	  } 	  public int getPageId() { 		  return this.mPageId; 	  } 	  public void setPage(PageViewP1 pageViewP1) { 		  this.mPage = pageViewP1; 	  } 	  public PageViewP1 getPage() { 		  return this.mPage; 	  } 	  public void setCorner(int corner) { 		  this.mCorner = corner; 	  } 	  public int getCorner() { 		  return this.mCorner; 	  } 	  protected void dispatchDraw(Canvas canvas) { 		   			Log.v("log dispatchDraw:", "drawing back page"+mPageTurning); //		  if ((this.mPageTurning) && (this.mPage != null) && (computePageTurn())) { 		  if ((computePageTurn())&& (this.mPageTurning) && (this.mPage != null) ) { 			  this.mPage.setClipPath(this.mForegroundPath); 		  } 		  super.dispatchDraw(canvas); 		  if (this.mPageTurning) { 			  drawBackground(canvas); 			  drawBackPage(canvas); 			   			  if (!updateTimeStep()) { 				  this.mHandler.removeMessages(1); 				  if (this.mPage != null) { 					  this.mPage.onPageTurnFinished(canvas); 				  } 				  this.mPageTurning = false; 				  this.mStepping = false; 				  invalidate(); 			  } 		  } 	  } 	  public void startPageTurn(int mTimeStep) { 		  if ((this.mPage == null) && (this.mPageId != -1)) { 			  this.mPage = ((PageViewP1)findViewById(this.mPageId)); 		  } 		  if (this.mPage == null) { 			  return; 		  } 		  this.mPage.setPageTurner(this); 		  Drawable d = this.mPage.getPageBackground(); 		  if (d != null) { 			  this.mPageBackground = d; 		  } 		  d = this.mPage.getBackPage(); 		  if (d != null) { 			  this.mBackPage = d; 		  } 		  int corner = this.mPage.getCorner(); 		  if (corner != -1) { 			  this.mCorner = corner; 		  } //		  this.mStepping=false; 		  this.mPageTurning = true; 		  this.mTimeStep = mTimeStep; 		  this.mDrawnTimeStep = -1; 		  Message msg = this.mHandler.obtainMessage(1); 		  this.mNextTime = (SystemClock.uptimeMillis() + 5L); 		  this.mHandler.sendMessageAtTime(msg, this.mNextTime); 	  } 	  public void stepPageTurn() { 		  if (!this.mStepping) { 			  this.mStepping = true; 			  startPageTurn(this.mTimeStep); 		  } else { //			 			  refreshUI(); 		  } 	  } 	  public void refreshUI(){ 		  computePageTurn(); //		  		  this.invalidate(); 	  } 	  private void sendUIhandler(){ 		  Message msg = this.mHandler.obtainMessage(1); 		  this.mNextTime = (SystemClock.uptimeMillis() + 30L); 		  this.mHandler.sendMessageAtTime(msg, this.mNextTime); 	  } 	  private boolean updateTimeStep() { 		  if (this.mTimeStep >mMaxStep || this.mTimeStepthis.mMaxStep)) {		  if ( (this.mTimeStep this.mMaxStep)) {			  return false;		  }		  if (this.mPage == null) {			  return false;		  }		  this.mDrawnTimeStep = this.mTimeStep;		  View child = this.mPage.getChildAt(0);		  child.getDrawingRect(this.mChildRect);//		  this.mOuterOffsetX = (child.getLeft() - getLeft());//		  this.mOuterOffsetY = (child.getTop() - getTop());		  this.mOuterOffsetX = 0;		  this.mOuterOffsetY = 0; 		  float width = this.mChildRect.right;		  float height = this.mChildRect.bottom;		  if(!mStepping){			  this.mPivotX = (this.mTimeStep / 30.0f * width);		  }		  this.mForegroundPath = new Path();		  this.mBackPagePath = new Path();		  this.mBackgroundPath = new Path();		  float slope = width / (this.mPivotX - width);		  float y = this.mPivotX * slope; 		  this.mPageTurnCorner.x = 0.0F;		  this.mPageTurnCorner.y = height;		  this.mOppositeCorner.x = width;		  this.mOppositeCorner.y = 0.0F;		  float x0 = this.mPivotX;		  float cornerIntersect = height * width / (height + width);		  if ((this.mCorner & 0x1) != 0) {			  this.mPageTurnCorner.x = width;			  this.mOppositeCorner.x = 0.0F;			  x0 = width - x0;		  } 		  if ((this.mCorner & 0x2) != 0) {			  this.mPageTurnCorner.y = 0.0F;			  this.mOppositeCorner.y = height;		  } 		  this.mPageDim.x = width;		  this.mPageDim.y = height;		  float page_slope; 		  if (this.mPivotX 2){			LinearGradient grad = new LinearGradient(					ex,ey,ex+(dx-ex)/4,ey+(dy-ey)/4,R.color.gray3,Color.TRANSPARENT,Shader.TileMode.CLAMP);			Paint p=new Paint();		    p.setShader(grad);//		    p.setAlpha(120);		    canvas.drawPath(this.mBackgroundPath,p);		    //end test		  	}		  canvas.restore(); 	  } 	  private void drawBackPage(Canvas canvas) {		  float width = this.mChildRect.right;		  float height = this.mChildRect.bottom;		  canvas.save();//		  canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));		  canvas.clipPath(this.mBackPagePath, Region.Op.INTERSECT);		  float xShift = 2.0F * this.mPivotX - width;		  float xRotate = width - this.mPivotX;		  float yRotate = height;		  if ((this.mCorner & 0x1) != 0) {			  xShift = width - 2.0F * this.mPivotX;			  xRotate = this.mPivotX;		  }		  if ((this.mCorner & 0x2) != 0) {			  yRotate = 0.0F;		  }		  canvas.translate(this.mOuterOffsetX + xShift, this.mOuterOffsetY);		  canvas.rotate(this.mRotation, xRotate, yRotate); 		  //画原本的背面		  if (this.mBackPage != null) {			  this.mBackPage.setBounds(0, 0, this.mChildRect.right, this.mChildRect.bottom);			  this.mBackPage.draw(canvas);		  }		  //画回调函数中的画背面		  if (this.mPage != null) {				Log.v("log2 drawBackPage2:", "drawing back page");			  this.mPage.drawBackPage(canvas);		  } 		  canvas.restore();		  canvas.save();//		    LinearGradient grad = new LinearGradient(					ex,ey,ex-(ex-bx)/4,ey-(ey-by)/4,R.color.gray3,0xC9C9C9,Shader.TileMode.CLAMP);			Paint p=new Paint();		    p.setShader(grad);//		    p.setAlpha(120);		    canvas.drawPath(this.mBackPagePath,p);		    canvas.restore();		    //中间阴影问题,起点蓝色-》 白色-》 蓝色终点,这样起点前和终点后的区域也为蓝色了。		    canvas.save();//		    canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG));		    LinearGradient grad1 = new LinearGradient(		    		ex-(ex-bx)/4,ey-(ey-by)/4,bx,by,0xC9C9C9,R.color.gray3,Shader.TileMode.CLAMP);			Paint p1=new Paint();			p1.setShader(grad1);//			p1.setAlpha(120);		    canvas.drawPath(this.mBackPagePath,p1);		    canvas.restore();//		    	  } 	  public int getmTimeStep(){ 		  return mTimeStep;	  }	  public void setmTimeStep(int mTimeStep ){ 		  this.mTimeStep= mTimeStep;	  }	  public boolean getmStepping(){ 		  return mStepping;	  }	  public void setmStepping(boolean mStepping ){ 		  this.mStepping= mStepping;	  } 	  public void setmStepLen(int mStepLen){		  this.mStepLen=mStepLen;	  }	  public int getmStepLen(){		  return this.mStepLen;	  } 	  public void setmMaxStep(int mMaxStep){		  this.mMaxStep=mMaxStep;	  }	  public int getmMaxStep(){		  return this.mMaxStep;	  } 	public void setPreStart(int where)	{		switch (where)		{			case NEXT:			case LAST:				mWhere = where;				break; 			default:				mWhere = KEEP;				break;		} 		isBgInit = true;		isBackInit = true; 	} }
?

第二个view类pageView.java:

public class PageViewP1 extends RelativeLayout {	public static final int CORNER_BOTTOM_LEFT = 0;	public static final int CORNER_BOTTOM_RIGHT = 1;	public static final int CORNER_TOP_LEFT = 2;	public static final int CORNER_TOP_RIGHT = 3;	private Path mClipPath;	private PageTurnerViewP1 mPageTurner;	private Callback mCallback;	private int mCorner;	private Drawable mBackPage;	private Drawable mPageBackground; 	public PageViewP1(Context context) {		super(context);	} 	public PageViewP1(Context context, AttributeSet attrs ) {		super(context, attrs ); 		this.mBackPage =this.getBackground();		this.mCorner = -1;	} 	void setPageTurner(PageTurnerViewP1 pageTurnerViewP1) {		this.mPageTurner = pageTurnerViewP1;	} 	void setClipPath(Path clipPath) {		this.mClipPath = clipPath;	} 	public void setCallback(Callback callback)  {		this.mCallback = callback;	} 	void drawBackPage(Canvas canvas) {	   if (this.mCallback != null)		   this.mCallback.onDrawBackPage(canvas);	} 	void drawBackground(Canvas canvas) {		if (this.mCallback != null)			this.mCallback.onDrawBackground(canvas);	} 	public void startPageTurn() {		if (this.mPageTurner != null)			this.mPageTurner.startPageTurn(0);	} 	void onPageTurnFinished(Canvas canvas) {		this.mCallback.onPageTurnFinished(canvas);		this.mClipPath = null;	} 	protected void dispatchDraw(Canvas canvas) {		if (this.mClipPath != null) {			canvas.save();			canvas.clipPath(this.mClipPath, Region.Op.INTERSECT);		}		super.dispatchDraw(canvas);		if (this.mClipPath != null)			canvas.restore();	} 	public void setCorner(int corner) {		this.mCorner = corner;	} 	public int getCorner() {		return this.mCorner;	} 	public void setBackPage(Drawable backPage) {		this.mBackPage = backPage;	} 	public Drawable getBackPage() {		return this.mBackPage;	} 	public void setPageBackground(Drawable background) {		this.mPageBackground = background;	} 	public Drawable getPageBackground() {		return this.mPageBackground;	} 	public static abstract class Callback {		public void onDrawBackPage(Canvas canvas) {			Log.v("Callback", "drawing back page");		}		public void onDrawBackground(Canvas canvas) {			Log.v("Callback2", "drawing back page");		}		public void onPageTurnFinished(Canvas canvas) {			Log.v("Callback3", "drawing back page");		}	}}
? ? ??转载请注明来自:?5进制空间-android区

如果这两个view类没研究明白怎么用的话,可以去android 翻页卷曲效果里面寻找获取pageDemo.java,获得使用方法。

  相关解决方案