先上个效果图:

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

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

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

view sourceprint?
001.public class PageTurnerViewP1 extends RelativeLayout{ 
002. 
003.private static final int CORNER_RIGHT_MASK = 1; 
004.private static final int CORNER_TOP_MASK = 2; 
005.public static final int CORNER_BOTTOM_LEFT = 0; 
006.public static final int CORNER_BOTTOM_RIGHT = 1; 
007.public static final int CORNER_TOP_LEFT = 2; 
008.public static final int CORNER_TOP_RIGHT = 3; 
009.private static final int INVALIDATE = 1; 
010.private static final int INITIAL_TIME_DELAY = 100; 
011.private static final int TIME_DELAY = 10; 
012.//    private static final int TIME_STEPS = 30; 
013.private boolean mPageTurning; 
014.private boolean mStepping; 
015.public long mNextTime; 
016.private int mTimeStep; 
017.private int mDrawnTimeStep; 
018.private int mCorner; 
019.private Drawable mBackPage; 
020.private Drawable mPageBackground; 
021.private Path mForegroundPath; 
022.private Path mBackPagePath; 
023.private Path mBackgroundPath; 
024.private float mRotation; 
025.private Rect mChildRect = new Rect(); 
026.private int mOuterOffsetX; 
027.private int mOuterOffsetY; 
028.public float mPivotX; 
029.private int mPageId; 
030.private PageViewP1 mPage; 
031.private PointF mPageTurnCorner = new PointF(); 
032.private PointF mOppositeCorner = new PointF(); 
033.private PointF mPageDim = new PointF(); 
034.private int mStepLen = 1; 
035.public static final int KEEP = 0; 
036.public static final int NEXT = 1; 
037.public static final int LAST = 2; 
038.public int mWhere = KEEP; 
039.public boolean isBgInit = true
040.public boolean isBackInit = true
041.private  float ax,ay,bx,by,cx,cy,dx,dy,ex,ey,c0x,c0y; 
042.private int mMaxStep=30; 
043.public final Handler mHandler = new Handler() { 
044.public void handleMessage(Message msg) { 
045.if (msg.what != 1) { return; } 
046.//            PageTurnerViewP1.this.invalidate(); 
047.refreshUI(); 
048.//            PageTurnerViewP1.this.invalidate((int)bx, (int)ay, (int)dx, (int)dy); 
049.if (PageTurnerViewP1.this.mStepping) { return; } 
050.msg = obtainMessage(1); 
051.long current = SystemClock.uptimeMillis(); 
052.if (PageTurnerViewP1.this.mNextTime < current) { 
053.//PageTurnerViewP1.access$102(PageTurnerViewP1.this, current + 10L); 
054.PageTurnerViewP1.this.mNextTime= current + 5L; 
055.
056.sendMessageAtTime(msg, PageTurnerViewP1.this.mNextTime); 
057.//PageTurnerViewP1.access$114(PageTurnerViewP1.this, 10L); 
058.PageTurnerViewP1.this.mNextTime+= 5L; 
059.
060.}; 
061. 
062. 
063.public PageTurnerViewP1(Context context) { 
064.super(context); 
065.Log.i("==================== PageTurnerViewP1(Context context) =================""" this); 
066.
067. 
068.public PageTurnerViewP1(Context context, AttributeSet attrs) { 
069.super(context, attrs); 
070. 
071.//        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PageTurner); 
072. 
073.//        this.mBackPage = a.getDrawable(1); 
074.//        this.mPageBackground = a.getDrawable(0); 
075.// 
076.//        this.mPageId = a.getResourceId(3, -1); 
077.// 
078.//        this.mCorner = a.getInt(2, 0); 
079.//          this.mBackPage = this.getResources().getDrawable(com.tom.clip.R.drawable.a5); 
080.//          this.mPageBackground =this.getResources().getDrawable(com.tom.clip.R.drawable.a6); 
081. 
082.this.mPageId = -1; 
083.this.mCorner = -1; 
084.
085. 
086.protected void onFinishInflate() { 
087.super.onFinishInflate(); 
088.if (this.mPageId != -1) { 
089.this.mPage = ((PageViewP1)findViewById(this.mPageId)); 
090.if (this.mPage != null) 
091.this.mPage.setPageTurner(this); 
092.
093.
094. 
095.public void setPageId(int pageId) { 
096.this.mPageId = pageId; 
097.this.mPage = ((PageViewP1)findViewById(this.mPageId)); 
098.if (this.mPage != null) 
099.this.mPage.setPageTurner(this); 
100.
101. 
102.public int getPageId() { 
103.return this.mPageId; 
104.
105. 
106.public void setPage(PageViewP1 pageViewP1) { 
107.this.mPage = pageViewP1; 
108.
109. 
110.public PageViewP1 getPage() { 
111.return this.mPage; 
112.
113. 
114.public void setCorner(int corner) { 
115.this.mCorner = corner; 
116.
117. 
118.public int getCorner() { 
119.return this.mCorner; 
120.
121. 
122.protected void dispatchDraw(Canvas canvas) { 
123. 
124.Log.v("log dispatchDraw:""drawing back page"+mPageTurning); 
125.//        if ((this.mPageTurning) && (this.mPage != null) && (computePageTurn())) { 
126.if ((computePageTurn())&& (this.mPageTurning) && (this.mPage != null) ) { 
127.this.mPage.setClipPath(this.mForegroundPath); 
128.
129. 
130.super.dispatchDraw(canvas); 
131. 
132.if (this.mPageTurning) { 
133.drawBackground(canvas); 
134.drawBackPage(canvas); 
135. 
136.if (!updateTimeStep()) { 
137.this.mHandler.removeMessages(1); 
138.if (this.mPage != null) { 
139.this.mPage.onPageTurnFinished(canvas); 
140.
141.this.mPageTurning = false
142.this.mStepping = false
143.invalidate(); 
144.
145.
146.
147. 
148.public void startPageTurn(int mTimeStep) { 
149.if ((this.mPage == null) && (this.mPageId != -1)) { 
150.this.mPage = ((PageViewP1)findViewById(this.mPageId)); 
151.
152.if (this.mPage == null) { 
153.return
154.
155.this.mPage.setPageTurner(this); 
156.Drawable d = this.mPage.getPageBackground(); 
157.if (d != null) { 
158.this.mPageBackground = d; 
159.
160. 
161.d = this.mPage.getBackPage(); 
162.if (d != null) { 
163.this.mBackPage = d; 
164.
165. 
166.int corner = this.mPage.getCorner(); 
167.if (corner != -1) { 
168.this.mCorner = corner; 
169.
170.//        this.mStepping=false; 
171.this.mPageTurning = true
172.this.mTimeStep = mTimeStep; 
173.this.mDrawnTimeStep = -1; 
174.Message msg = this.mHandler.obtainMessage(1); 
175.this.mNextTime = (SystemClock.uptimeMillis() + 5L); 
176.this.mHandler.sendMessageAtTime(msg, this.mNextTime); 
177.
178. 
179.public void stepPageTurn() { 
180.if (!this.mStepping) { 
181.this.mStepping = true
182.startPageTurn(this.mTimeStep); 
183.else 
184.//          te((int)bx, 0, (int)mPageTurnCorner.x, (int)mPageTurnCorner.y); 
185.//            sendUIhandler(); 
186.refreshUI(); 
187.
188.
189.public void refreshUI(){ 
190.computePageTurn(); 
191.//   
192.this.invalidate(); 
193.
194.private void sendUIhandler(){ 
195.Message msg = this.mHandler.obtainMessage(1); 
196.this.mNextTime = (SystemClock.uptimeMillis() + 30L); 
197.this.mHandler.sendMessageAtTime(msg, this.mNextTime); 
198.
199.private boolean updateTimeStep() { 
200.if (this.mTimeStep >mMaxStep || this.mTimeStep<0) { 
201.return false
202.
203.this.mTimeStep +=mStepLen; 
204.return true
205.
206. 
207.private boolean computePageTurn() { 
208.//        if ((this.mDrawnTimeStep == this.mTimeStep) ||(this.mTimeStep <0)||(this.mTimeStep >this.mMaxStep)) { 
209.if ( (this.mTimeStep <0)||(this.mTimeStep >this.mMaxStep)) { 
210.return false
211.
212.if (this.mPage == null) { 
213.return false
214.
215.this.mDrawnTimeStep = this.mTimeStep; 
216.View child = this.mPage.getChildAt(0); 
217.child.getDrawingRect(this.mChildRect); 
218.//        this.mOuterOffsetX = (child.getLeft() - getLeft()); 
219.//        this.mOuterOffsetY = (child.getTop() - getTop()); 
220.this.mOuterOffsetX = 0; 
221.this.mOuterOffsetY = 0; 
222. 
223.float width = this.mChildRect.right; 
224.float height = this.mChildRect.bottom; 
225.if(!mStepping){ 
226.this.mPivotX = (this.mTimeStep / 30.0f * width); 
227.
228.this.mForegroundPath = new Path(); 
229.this.mBackPagePath = new Path(); 
230.this.mBackgroundPath = new Path(); 
231.float slope = width / (this.mPivotX - width); 
232.float y = this.mPivotX * slope; 
233. 
234.this.mPageTurnCorner.x = 0.0F; 
235.this.mPageTurnCorner.y = height; 
236.this.mOppositeCorner.x = width; 
237.this.mOppositeCorner.y = 0.0F; 
238.float x0 = this.mPivotX; 
239.float cornerIntersect = height * width / (height + width); 
240.if ((this.mCorner & 0x1) != 0) { 
241.this.mPageTurnCorner.x = width; 
242.this.mOppositeCorner.x = 0.0F; 
243.x0 = width - x0; 
244.
245. 
246.if ((this.mCorner & 0x2) != 0) { 
247.this.mPageTurnCorner.y = 0.0F; 
248.this.mOppositeCorner.y = height; 
249.
250. 
251.this.mPageDim.x = width; 
252.this.mPageDim.y = height; 
253.float page_slope; 
254. 
255.if (this.mPivotX <= cornerIntersect) { 
256.page_slope = firstHalfPageTurn(this.mPageDim, this.mPageTurnCorner, this.mOppositeCorner, x0, slope, y); 
257.else 
258.page_slope = secondHalfPageTurn(this.mPageDim, this.mPageTurnCorner, this.mOppositeCorner, x0, slope, y); 
259.
260. 
261.this.mRotation = (float)Math.atan(page_slope); 
262. 
263.this.mRotation = (float)(-this.mRotation * 180.0D / 3.141592653589793D); 
264. 
265.return true
266.
267. 
268.private float firstHalfPageTurn(PointF pageDim, PointF pageTurnCorner, PointF oppositeCorner, float xPivot, float slope, float y) { 
269.float width = pageDim.x; 
270.float height = pageDim.y; 
271.View child = this.mPage.getChildAt(0); 
272.int innerOffsetX = child.getLeft() - this.mPage.getLeft(); 
273.int innerOffsetY = child.getTop() - this.mPage.getTop(); 
274. 
275.float y1 = height + y; 
276. 
277.float x2 = (float)(2.0D * y / (slope + 1.0D / slope)); 
278.float y2 = height + x2 / slope; 
279.float page_slope = (height - y2) / (x2 - this.mPivotX); 
280.if ((this.mCorner & 0x1) != 0) { 
281.x2 = width - x2; 
282.page_slope = -page_slope; 
283.
284.if ((this.mCorner & 0x2) != 0) { 
285.y1 = height - y1; 
286.y2 = height - y2; 
287.page_slope = -page_slope; 
288.
289. 
290.float x0 = xPivot; 
291.float x1 = pageTurnCorner.x; 
292. 
293. 
294.//a点是右上角,b点位左下角,c点为右下角,d点为固定的右下角 
295.ax=this.mOuterOffsetX + x1; 
296.ay=this.mOuterOffsetY + y1; 
297. 
298.bx=this.mOuterOffsetX + x2; 
299.by=this.mOuterOffsetY + y2; 
300. 
301.cx=this.mOuterOffsetX + x0; 
302.cy=this.mOuterOffsetY + pageTurnCorner.y; 
303. 
304.dx=this.mOuterOffsetX + pageTurnCorner.x; 
305.dy=this.mOuterOffsetY + pageTurnCorner.y; 
306. 
307.ex=(dx+bx)/2; 
308.ey=(dy+by)/2; 
309. 
310.this.mForegroundPath.moveTo(innerOffsetX + x1, innerOffsetY + y1); 
311.this.mForegroundPath.lineTo(innerOffsetX + pageTurnCorner.x, innerOffsetY + oppositeCorner.y); 
312.this.mForegroundPath.lineTo(innerOffsetX + oppositeCorner.x, innerOffsetY + oppositeCorner.y); 
313.this.mForegroundPath.lineTo(innerOffsetX + oppositeCorner.x, innerOffsetY + pageTurnCorner.y); 
314.this.mForegroundPath.lineTo(innerOffsetX + x0, innerOffsetY + pageTurnCorner.y); 
315.this.mForegroundPath.lineTo(innerOffsetX + x2, innerOffsetY + y2); 
316.//        this.mForegroundPath.quadTo(ex, ey, bx, by); 
317.this.mForegroundPath.lineTo(innerOffsetX + x1, innerOffsetY + y1); 
318. 
319.this.mBackPagePath.moveTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
320.this.mBackPagePath.lineTo(this.mOuterOffsetX + x2, this.mOuterOffsetY + y2); 
321.//b到c的那条线,可以考虑画个弧线 
322.this.mBackPagePath.lineTo(this.mOuterOffsetX + x0, this.mOuterOffsetY + pageTurnCorner.y); 
323.//        this.mBackPagePath.arcTo(new RectF(bx,by,cx,cy), 220, 180,false); 
324.//        this.mBackPagePath.quadTo(ex, ey, cx, cy); 
325.//        this.mBackPagePath.cubicTo(100, -50, 200, 50, cx, cy);//贝赛尔曲线 
326.this.mBackPagePath.lineTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
327. 
328. 
329.this.mBackgroundPath.moveTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
330.this.mBackgroundPath.lineTo(this.mOuterOffsetX + x0, this.mOuterOffsetY + pageTurnCorner.y); 
331.this.mBackgroundPath.lineTo(this.mOuterOffsetX + pageTurnCorner.x, this.mOuterOffsetY + pageTurnCorner.y); 
332.this.mBackgroundPath.lineTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
333. 
334.return page_slope; 
335.
336. 
337. 
338.private float secondHalfPageTurn(PointF pageDim, PointF pageTurnCorner, PointF oppositeCorner, float xPivot, float slope, float y) { 
339.float width = pageDim.x; 
340.float height = pageDim.y; 
341.View child = this.mPage.getChildAt(0); 
342.int xOffset = child.getLeft() - this.mPage.getLeft(); 
343.int yOffset = child.getTop() - this.mPage.getTop(); 
344. 
345.float y1 = 0.0F; 
346.float x1 = width - (height + width) * (width - this.mPivotX) / width; 
347. 
348.float x3 = (float)(2.0D * y / (slope + 1.0D / slope)); 
349.float y3 = height + x3 / slope; 
350.float page_slope = (height - y3) / (x3 - this.mPivotX); 
351.float b = height - x1 * page_slope; 
352.float x2 = (float)((-y - b) / (page_slope + 1.0D / page_slope)); 
353.float y2 = (x1 - x2) * page_slope; 
354. 
355.if ((this.mCorner & 0x1) != 0) { 
356.x1 = width - x1; 
357.x2 = width - x2; 
358.x3 = width - x3; 
359.page_slope = -page_slope; 
360.
361.if ((this.mCorner & 0x2) != 0) { 
362.y1 = height - y1; 
363.y2 = height - y2; 
364.y3 = height - y3; 
365.page_slope = -page_slope; 
366.
367. 
368.float x0 = xPivot; 
369. 
370.this.mForegroundPath.moveTo(xOffset + x1, yOffset + y1); 
371.this.mForegroundPath.lineTo(xOffset + oppositeCorner.x, yOffset + oppositeCorner.y); 
372.this.mForegroundPath.lineTo(xOffset + oppositeCorner.x, yOffset + pageTurnCorner.y); 
373.this.mForegroundPath.lineTo(xOffset + x0, yOffset + pageTurnCorner.y); 
374.this.mForegroundPath.lineTo(xOffset + x1, yOffset + y1); 
375. 
376.//a点是右上角,c0点位左上角,b点为左下角,d点为固定的右下角 
377.ax=this.mOuterOffsetX + x1; 
378.ay=this.mOuterOffsetY + y1; 
379. 
380.c0x=this.mOuterOffsetX + x2; 
381.c0y=this.mOuterOffsetY + y2; 
382. 
383.bx=this.mOuterOffsetX + x3; 
384.by=this.mOuterOffsetY + y3; 
385.cx=this.mOuterOffsetX + x0; 
386.cy=this.mOuterOffsetY + pageTurnCorner.y; 
387. 
388.dx=this.mOuterOffsetX + pageTurnCorner.x; 
389.dy=this.mOuterOffsetY + pageTurnCorner.y; 
390. 
391.ex=(dx+bx)/2; 
392.ey=(dy+by)/2; 
393. 
394.this.mBackPagePath.moveTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
395.this.mBackPagePath.lineTo(this.mOuterOffsetX + x2, this.mOuterOffsetY + y2); 
396.this.mBackPagePath.lineTo(this.mOuterOffsetX + x3, this.mOuterOffsetY + y3); 
397.this.mBackPagePath.lineTo(this.mOuterOffsetX + x0, this.mOuterOffsetY + pageTurnCorner.y); 
398.//        this.mBackPagePath.quadTo(ex, ey, cx, cy); 
399.this.mBackPagePath.lineTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
400. 
401. 
402. 
403.this.mBackgroundPath.moveTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
404.this.mBackgroundPath.lineTo(this.mOuterOffsetX + x0, this.mOuterOffsetY + pageTurnCorner.y); 
405.this.mBackgroundPath.lineTo(this.mOuterOffsetX + pageTurnCorner.x, this.mOuterOffsetY + pageTurnCorner.y); 
406.this.mBackgroundPath.lineTo(this.mOuterOffsetX + pageTurnCorner.x, this.mOuterOffsetY + oppositeCorner.y); 
407.this.mBackgroundPath.lineTo(this.mOuterOffsetX + x1, this.mOuterOffsetY + y1); 
408. 
409.return page_slope; 
410.
411. 
412.private void drawBackground(Canvas canvas) { 
413.canvas.save(); 
414.//        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); 
415.canvas.clipPath(this.mBackgroundPath, Region.Op.INTERSECT); 
416.canvas.translate(this.mOuterOffsetX, this.mOuterOffsetY); 
417. 
418.if (this.mPageBackground != null) { 
419.this.mPageBackground.setBounds(0, 0, this.mChildRect.right, this.mChildRect.bottom); 
420. 
421.this.mPageBackground.draw(canvas); 
422.
423.if (this.mPage != null) { 
424.this.mPage.drawBackground(canvas); 
425.
426. 
427.// add drop shadow start test 
428.if(mTimeStep<=29&&ex>2){ 
429.LinearGradient grad = new LinearGradient( 
430.ex,ey,ex+(dx-ex)/4,ey+(dy-ey)/4,R.color.gray3,Color.TRANSPARENT,Shader.TileMode.CLAMP); 
431.Paint p=new Paint(); 
432.p.setShader(grad); 
433.//          p.setAlpha(120); 
434.canvas.drawPath(this.mBackgroundPath,p); 
435.//end test 
436.
437.canvas.restore(); 
438. 
439. 
440.
441. 
442.private void drawBackPage(Canvas canvas) { 
443.float width = this.mChildRect.right; 
444.float height = this.mChildRect.bottom; 
445.canvas.save(); 
446.//        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); 
447.canvas.clipPath(this.mBackPagePath, Region.Op.INTERSECT); 
448.float xShift = 2.0F * this.mPivotX - width; 
449.float xRotate = width - this.mPivotX; 
450.float yRotate = height; 
451.if ((this.mCorner & 0x1) != 0) { 
452.xShift = width - 2.0F * this.mPivotX; 
453.xRotate = this.mPivotX; 
454.
455.if ((this.mCorner & 0x2) != 0) { 
456.yRotate = 0.0F; 
457.
458.canvas.translate(this.mOuterOffsetX + xShift, this.mOuterOffsetY); 
459.canvas.rotate(this.mRotation, xRotate, yRotate); 
460. 
461.//画原本的背面 
462.if (this.mBackPage != null) { 
463.this.mBackPage.setBounds(0, 0, this.mChildRect.right, this.mChildRect.bottom); 
464.this.mBackPage.draw(canvas); 
465.
466.//画回调函数中的画背面 
467.if (this.mPage != null) { 
468.Log.v("log2 drawBackPage2:""drawing back page"); 
469.this.mPage.drawBackPage(canvas); 
470.
471. 
472.canvas.restore(); 
473.canvas.save(); 
474.//        canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); 
475.//        int[] colors={Color.BLACK,Color.GRAY,Color.BLACK}; 
476.//          LinearGradient grad = new LinearGradient( 
477.//                  ex,ey,bx,by,colors,null,Shader.TileMode.CLAMP); 
478.//          Paint p=new Paint(); 
479.//          p.setShader(grad); 
480.//          p.setAlpha(120); 
481.//          canvas.drawPath(this.mBackPagePath,p); 
482.LinearGradient grad = new LinearGradient( 
483.ex,ey,ex-(ex-bx)/4,ey-(ey-by)/4,R.color.gray3,0xC9C9C9,Shader.TileMode.CLAMP); 
484.Paint p=new Paint(); 
485.p.setShader(grad); 
486.//          p.setAlpha(120); 
487.canvas.drawPath(this.mBackPagePath,p); 
488.canvas.restore(); 
489.//中间阴影问题,起点蓝色-》 白色-》 蓝色终点,这样起点前和终点后的区域也为蓝色了。 
490.canvas.save(); 
491.//          canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG)); 
492.LinearGradient grad1 = new LinearGradient( 
493.ex-(ex-bx)/4,ey-(ey-by)/4,bx,by,0xC9C9C9,R.color.gray3,Shader.TileMode.CLAMP); 
494.Paint p1=new Paint(); 
495.p1.setShader(grad1); 
496.//          p1.setAlpha(120); 
497.canvas.drawPath(this.mBackPagePath,p1); 
498.canvas.restore(); 
499.// 
500. 
501.
502. 
503.public int getmTimeStep(){ 
504. 
505.return mTimeStep; 
506.
507.public void setmTimeStep(int mTimeStep ){ 
508. 
509.this.mTimeStep= mTimeStep; 
510.
511.public boolean getmStepping(){ 
512. 
513.return mStepping; 
514.
515.public void setmStepping(boolean mStepping ){ 
516. 
517.this.mStepping= mStepping; 
518.
519. 
520.public void setmStepLen(int mStepLen){ 
521.this.mStepLen=mStepLen; 
522.
523.public int getmStepLen(){ 
524.return this.mStepLen; 
525.
526. 
527.public void setmMaxStep(int mMaxStep){ 
528.this.mMaxStep=mMaxStep; 
529.
530.public int getmMaxStep(){ 
531.return this.mMaxStep; 
532.
533. 
534.public void setPreStart(int where) 
535.
536.switch (where)  
537.
538.case NEXT: 
539.case LAST: 
540.mWhere = where; 
541.break
542. 
543.default
544.mWhere = KEEP; 
545.break
546.
547. 
548.isBgInit = true
549.isBackInit = true
550. 
551.
552. 
553. 
554.

第二个view类pageView.java:

view sourceprint?
001.public class PageViewP1 extends RelativeLayout { 
002.public static final int CORNER_BOTTOM_LEFT = 0; 
003.public static final int CORNER_BOTTOM_RIGHT = 1; 
004.public static final int CORNER_TOP_LEFT = 2; 
005.public static final int CORNER_TOP_RIGHT = 3; 
006.private Path mClipPath; 
007.private PageTurnerViewP1 mPageTurner; 
008.private Callback mCallback; 
009.private int mCorner; 
010.private Drawable mBackPage; 
011.private Drawable mPageBackground; 
012. 
013.public PageViewP1(Context context) { 
014.super(context); 
015.
016. 
017.public PageViewP1(Context context, AttributeSet attrs ) { 
018.super(context, attrs ); 
019.//      TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PageTurner); 
020.//      this.getResources().getDrawable(com.tom.clip.R.drawable.page); 
021.//      this.mBackPage = this.getResources().getDrawable(com.tom.clip.R.drawable.a1); 
022.//      this.mPageBackground =this.getResources().getDrawable(com.tom.clip.R.drawable.a2); 
023. 
024.this.mBackPage =this.getBackground(); 
025.this.mCorner = -1; 
026.
027. 
028.void setPageTurner(PageTurnerViewP1 pageTurnerViewP1) { 
029.this.mPageTurner = pageTurnerViewP1; 
030.
031. 
032.void setClipPath(Path clipPath) { 
033.this.mClipPath = clipPath; 
034.
035. 
036.public void setCallback(Callback callback)  { 
037.this.mCallback = callback; 
038.
039. 
040.void drawBackPage(Canvas canvas) { 
041.if (this.mCallback != null) 
042.this.mCallback.onDrawBackPage(canvas); 
043.
044. 
045.void drawBackground(Canvas canvas) { 
046.if (this.mCallback != null) 
047.this.mCallback.onDrawBackground(canvas); 
048.
049. 
050.public void startPageTurn() { 
051.if (this.mPageTurner != null) 
052.this.mPageTurner.startPageTurn(0); 
053.
054. 
055.void onPageTurnFinished(Canvas canvas) { 
056.this.mCallback.onPageTurnFinished(canvas); 
057.this.mClipPath = null; 
058.
059. 
060.protected void dispatchDraw(Canvas canvas) { 
061.if (this.mClipPath != null) { 
062.canvas.save(); 
063.canvas.clipPath(this.mClipPath, Region.Op.INTERSECT); 
064.
065.super.dispatchDraw(canvas); 
066.if (this.mClipPath != null) 
067.canvas.restore(); 
068.
069. 
070.public void setCorner(int corner) { 
071.this.mCorner = corner; 
072.
073. 
074.public int getCorner() { 
075.return this.mCorner; 
076.
077. 
078.public void setBackPage(Drawable backPage) { 
079.this.mBackPage = backPage; 
080.
081. 
082.public Drawable getBackPage() { 
083.return this.mBackPage; 
084.
085. 
086.public void setPageBackground(Drawable background) { 
087.this.mPageBackground = background; 
088.
089. 
090.public Drawable getPageBackground() { 
091.return this.mPageBackground; 
092.
093. 
094.public static abstract class Callback { 
095.public void onDrawBackPage(Canvas canvas) { 
096.Log.v("Callback""drawing back page"); 
097.
098.public void onDrawBackground(Canvas canvas) { 
099.Log.v("Callback2""drawing back page"); 
100.
101.public void onPageTurnFinished(Canvas canvas) { 
102.Log.v("Callback3""drawing back page"); 
103.
104.
105.

android 翻页卷曲效果 电子书翻页相关推荐

  1. python翻页_python实现电子书翻页小程序

    本文实例为大家分享了python实现电子书翻页的具体代码,供大家参考,具体内容如下 1.题目: 电子书翻页: (1)自动翻页:每次默认读三行,读完之后睡两秒,直到把所有内容全部读出来 (2)手动翻页: ...

  2. android 日历翻页动画,Android 仿日历翻页、仿htc时钟翻页、数字翻页切换效果

    废话不多说,效果图: 自定义控件找自网络,使用相对简单,具体还没有来得及深入研究,只是先用笨方法大概实现了想要的效果,后续有空会仔细研究再更新文章, 本demo切换方法是用的笨方法,也就是由新数字和旧 ...

  3. android 阅读器自动滚动,在Android手机上实现阅读器翻页效果.doc

    在Android手机上实现阅读器翻页效果 先了解各个字母表示的含义:A-把书页翻起来后看到的背面区域B-把书页翻起来后看到的下一页的一角C-当前页的可见部分.a-手指滑动页角到达的位置b-当前页翻起来 ...

  4. android 翻书动画效果怎么做,android ViewPager实现滑动翻页效果实例代码

    实现ViewPager的滑动翻页效果可以使用ViewPager的setPageTransformer方法,如下: import android.content.Context; import andr ...

  5. HTML5电子书翻页效果 代码特效+鼠标点击拖拽滑动翻页+点击书页内容放大+不支持中文

    介绍 源码名称:[HTML5电子书翻页效果]代码特效+鼠标点击拖拽滑动翻页+点击书页内容放大+不支持中文 源码大小:237KB 开发语言:PHP+Mysql 操作系统:Windows,Linux 源码 ...

  6. javascript移动端 电子书 翻页效果

    1.后端给一长串的纯文本 2.前端根据屏幕的高度,将文本切割为 n 页 3.使用插件 turn.js 将切割好的每页,加上翻书效果 <!DOCTYPE html> <html lan ...

  7. android sdio 时钟 ios-clock,【ios学习】OneClock的翻页时钟效果是如何实现的

    OneClock目前的三个表盘中用户最喜欢的是翻页时钟.翻页效果是表盘的核心,也是我花时间调试最久的细节.经过7次的产品迭代,终于调整到了一个合适的效果. 实现这个动效的方法只需用到CABasicAn ...

  8. 在线电子书翻页效果 Turn.js

    1 html中引入 <script type="text/javascript" src="js/turn.js"></script> ...

  9. 6个超炫酷的HTML5电子书翻页动画【转】

    6个超炫酷的HTML5电子书翻页动画 WebGL 演示网址:http://bookcase.chromeexperiments.com 相信大家一定遇到过一些电子书网站,我们可以通过像看书一样翻页来浏 ...

最新文章

  1. java上机练习01
  2. python之SSH远程登录
  3. 2019牛客暑期多校训练营(第五场)- generator 1
  4. html 改变文本框字体颜色,CSS更改文本框的字体颜色
  5. Maven项目报错invalid LOC header (bad signature)
  6. java界面编程(9) ------ 列表框
  7. python中iter是什么意思_python iter()与 __iter__()的区别
  8. 问答式验证码源码贡献(待续.......)
  9. 难怪这个文章评论多,原来被推荐了
  10. VS2015+Opencv3.2配置(一次配好)
  11. 杭电acm 1205 吃糖果
  12. 基于matlab的直流调速仿真系统代码,基于Matlab的双闭环直流调速系统仿真研究毕业设计论文...
  13. run.gps+trainer+uv+for+android,android 2.1(三星spica i5700)上的蓝牙问题配对工作但连接不起作用...
  14. ERP系统-库存子系统-领料单
  15. 生活中与现实中的字体应用体验俯拾皆是...
  16. 页面置换算法之 LRU算法
  17. java+ssm驾校管理教练用户驾校系统@ssm
  18. make_unique的使用
  19. 文献 | 肥胖这种病,心理因素是源头?
  20. 界面可视化(四):图像在PyQT5上的显示

热门文章

  1. 用Python分析韩国女团喜欢什么单词
  2. 【今日头条】【实习】放出一大波职位
  3. iOS Autorelease Runloop
  4. 如何将窗口变成半透明
  5. 不为人知的网络编程(十三):深入操作系统,彻底搞懂127.0.0.1本机网络通信
  6. 复旦大学2018--2019学年第二学期高等代数II期末考试情况分析
  7. python中RBG与BGR有什么不同
  8. 【网安神器篇】——mimikatz系统取证工具
  9. 三亚自由行攻略(自己穷游总结)
  10. 重读百度移动生态:“第一曲线”的创新“延长线”