首页 > 移动平台 > 详细

Android 翻页效果 电子书

时间:2014-02-10 16:28:42      阅读:438      评论:0      收藏:0      [点我收藏+]

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

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

先上个效果图:

bubuko.com,布布扣

bubuko.com,布布扣

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

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

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

bubuko.com,布布扣
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;
 
    }
 
}
bubuko.com,布布扣

第二个view类pageView.java

bubuko.com,布布扣
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");
        }
    }
}
bubuko.com,布布扣

PageTurnDemo.java

bubuko.com,布布扣
import java.lang.reflect.Field;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnTouchListener;
import android.widget.TextView;
 
public class PageTurnerDemo extends Activity {
 
private PageTurnerViewP1 pageturner;
private PageViewP1 page1;
private static final String TAG = "RUKIDEMO";
TextView text1;
TextView text2;
int screenWidth;
int screenHeight;
String content1;
String content2;
String currcontent;
private boolean marktest = true;
private int startX;
private int mMaxStep=30;
private int mAnimaStepLen=mMaxStep/8;
 
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
getWH();
 
setContentView(R.layout.main);
initPage();
pageturner = (PageTurnerViewP1) findViewById(R.id.pages);
pageturner.setPage(page1);
pageturner.setLongClickable(true);
pageturner.setOnTouchListener(pageontounchlistener);
// 自动运行surfaceCreated以及surfaceChanged
}
 
private void getWH() {
WindowManager windowManager = getWindowManager();
Display display = windowManager.getDefaultDisplay();
screenWidth = display.getWidth();
screenHeight = display.getHeight();
}
 
private void initPage() {
 
content1 =getResources().getString(R.string.content1);
content2 = getResources().getString(R.string.content2);
// 初始化两页内容
text1 = (TextView) findViewById(R.id.page1text);
// text1.setBackgroundResource(R.drawable.solopage);
text1.setText(content1);
 
text2 = (TextView) findViewById(R.id.page2text);
// text2.setBackgroundResource(R.drawable.solopage);
text2.setText(content2);
 
page1 = (PageViewP1) findViewById(R.id.page1);
// page1.setBackPage(this.getResources().getDrawable(R.drawable.solopage));
// page1.setPageBackground(this.getResources()
// .getDrawable(R.drawable.page));
page1.setCallback(pageturncallback);
page1.setCorner(PageViewP1.CORNER_TOP_LEFT);
// /++++++++++++++++++++++++++++++++++++++++++++///
}
 
PageViewP1.Callback pageturncallback = new PageViewP1.Callback() {
public void onDrawBackPage(Canvas canvas1) {
// apparently this gets called after every animation
// so if we wanted to we can draw the back page here
Log.v(TAG, "drawing back page");
// Paint mpaint = new Paint();
// mpaint.setColor(Color.BLUE);
// canvas1.drawText(
// "testtesttesttesttesttesttesttesttesttesttesttesttest",
// 150, 150, mpaint);
 
// canvas1.drawCircle(0,0,200,p); //参数3为画圆的半径,类型为float型。
 
// Shader setShader(Shader shader);
 
// text1.draw(canvas1);
}
 
public void onDrawBackground(Canvas canvas1) {
// apparently this gets called after every animation
// so if we wanted to we can draw the background here
Log.v(TAG, "drawing background");
 
// Paint mpaint = new Paint();
// Path path = new Path();
// mpaint.setColor(Color.BLACK);
// TextUtil mTextUtil;
// String string =
// "12345678910111213 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n"
// +"12345678910111213 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n"
// +"12345678910111213 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n"
// +"12345678910111213 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n"
// +"12345678910111213 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29\n";
// mTextUtil = new TextUtil(string, 15, 15, 350, 80, 0x000000,
// 0xff00ff,
// 235, 16);
// mTextUtil.InitText();
// mTextUtil.DrawText(canvas1);
// mpaint.setTextSize(textSize)
// canvas1.drawt
// page2.draw(canvas1);
 
canvas1.save();
// Paint p=new Paint();
// LinearGradient lg=new LinearGradient(0,0,100,100,Color.BLACK,Color.WHITE,Shader.TileMode.MIRROR);
// //参数一为渐变起初点坐标x位置,参数二为y轴位置,参数三和四分辨对应渐变终点,最后参数为平铺方式,这里设置为镜像
// p.setShader(lg);
//// canvas1.translate(200, 200);
// canvas1.skew(5, 5);
text2.draw(canvas1);
// myonDraw(canvas1);
canvas1.restore();
 
}
 
public void onPageTurnFinished(Canvas canvas1) {
// this gets called after the animation is done
// perphaps this is where we should change view to the new
// 在这里在换当前页内容到下一页的内容,这里假设text1是当前页内容
if (marktest) {
text1.setText(content2);
text2.setText(content1);
marktest = !marktest;
} else {
text2.setText(content2);
text1.setText(content1);
marktest = !marktest;
}
 
}
};
 
OnTouchListener pageontounchlistener = new OnTouchListener() {
 
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
final int action = event.getAction();
final int x = (int) event.getX();
final int y = (int) event.getY();
final float px = event.getX();
int itemLen = screenWidth / mMaxStep;
switch (action) {
case MotionEvent.ACTION_DOWN:
startX=x;
 
// LEFT
if (x < screenWidth / 2) {
// LT
if (y < screenHeight / 2) {
page1.setCorner(PageTurnerViewP1.CORNER_TOP_RIGHT);
// LB
} else {
page1.setCorner(PageTurnerViewP1.CORNER_BOTTOM_RIGHT);
}
// RIGHT
} else {
// RT
if (y < screenHeight / 2) {
page1.setCorner(PageTurnerViewP1.CORNER_TOP_RIGHT);
// RB
} else {
page1.setCorner(PageTurnerViewP1.CORNER_BOTTOM_RIGHT);
}
}
break;
case MotionEvent.ACTION_MOVE:
// pageturner.setPivotX(screenWidth-px);
// pageturner.invalidate();
//左侧起
if (startX pageturner.setmStepLen(-2);
pageturner.setmTimeStep((screenWidth-x) / itemLen);
pageturner.mPivotX=(screenWidth-x);
pageturner.stepPageTurn();
//右侧起
} else {
pageturner.setmStepLen(2);
pageturner.setmTimeStep((screenWidth-x) / itemLen);
pageturner.mPivotX=(screenWidth-x);
pageturner.stepPageTurn();
}
 
break;
case MotionEvent.ACTION_UP:
pageturner.setmStepLen(2);
pageturner.setmStepping(false);
//左侧起
if (startX screenWidth / 3){
pageturner.setmStepLen(-2);
}//左松
pageturner.startPageTurn((screenWidth-x) / itemLen);
//右侧起
} else {
pageturner.setmStepLen(2);
//左松
if(x < (screenWidth *2)/ 3){
pageturner.setmStepLen(2);
}else {//右松
pageturner.setmStepLen(-2);
}
pageturner.startPageTurn((screenWidth-x) / itemLen);
}
 
break;
case MotionEvent.ACTION_CANCEL:
}
 
return true;
}
 
};
 
}
bubuko.com,布布扣

 

Android 翻页效果 电子书

原文:http://www.cnblogs.com/duanxz/p/3542320.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!