package com.novelbook.android.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.animation.LinearInterpolator; import android.widget.Scroller; import com.novelbook.android.utils.CommonUtil; import com.novelbook.android.utils.PageFactory; import com.novelbook.android.view.animation.AnimationProvider; import com.novelbook.android.view.animation.CoverAnimation; import com.novelbook.android.view.animation.NoneAnimation; import com.novelbook.android.view.animation.SimulationAnimation; import com.novelbook.android.view.animation.SlideAnimation; import static com.novelbook.android.utils.Config.*; public class PageWidget extends View { private final static String TAG = "BookPageWidget"; private int mScreenWidth = 0; // 屏幕宽 private int mScreenHeight = 0; // 屏幕高 private Context mContext; //是否移动了 private Boolean isMove = false; //是否翻到下一页 private Boolean isNext = false; //是否取消翻页 private Boolean cancelPage = false; //是否没下一页或者上一页 private Boolean noNext = false; private int downX = 0; private int downY = 0; private int moveX = 0; private int moveY = 0; //翻页动画是否在执行 private Boolean isRuning =false; Bitmap mCurPageBitmap = null; // 当前页 Bitmap mNextPageBitmap = null; private AnimationProvider mAnimationProvider; Scroller mScroller; private int mBgColor = 0xFFCEC29C; private TouchListener mTouchListener; public PageWidget(Context context) { this(context,null); } public PageWidget(Context context, AttributeSet attrs) { this(context, attrs,0); } public PageWidget(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; initPage(); mScroller = new Scroller(getContext(),new LinearInterpolator()); mAnimationProvider = new SimulationAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); } private void initPage(){ WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metric = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(metric); mScreenWidth = metric.widthPixels; // mScreenHeight = metric.heightPixels; // mScreenHeight = CommonUtil.getDpi(mContext); mScreenHeight = CommonUtil.getScreenHeight(mContext); mCurPageBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.RGB_565); //android:LargeHeap=true use in manifest application mNextPageBitmap = Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.RGB_565); } public void setPageMode(int pageMode){ switch (pageMode){ case PAGE_MODE_SIMULATION: mAnimationProvider = new SimulationAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_COVER: mAnimationProvider = new CoverAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_SLIDE: mAnimationProvider = new SlideAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_NONE: mAnimationProvider = new NoneAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; default: mAnimationProvider = new SimulationAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); } } /* public void setPageMode2(int pageMode){ switch (pageMode){ case PAGE_MODE_SIMULATION: mAnimationProvider = new SimulationAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_COVER: mAnimationProvider = new CoverAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_SLIDE: mAnimationProvider = new SlideAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; case PAGE_MODE_NONE: mAnimationProvider = new NoneAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); break; default: mAnimationProvider = new SimulationAnimation(mCurPageBitmap,mNextPageBitmap,mScreenWidth,mScreenHeight); } } private Bitmap getCurPageBitmap(){ return Bitmap.createBitmap(mScreenWidth, mScreenHeight, Bitmap.Config.RGB_565); } private Bitmap getNextPageBitmap(){ return mNextPageBitmap; }*/ public Bitmap getCurPage(){ return mCurPageBitmap; } public Bitmap getNextPage(){ return mNextPageBitmap; } public void setBgColor(int color){ mBgColor = color; } @Override protected void onDraw(Canvas canvas) { // canvas.drawColor(0xFFAAAAAA); canvas.drawColor(mBgColor); // //Log.e("onDraw","isNext:" + isNext + " isRuning:" + isRuning); if (isRuning) { mAnimationProvider.drawMove(canvas); } else { mAnimationProvider.drawStatic(canvas); } } @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); if(!PageFactory.canTouch()){ return true; } /* if ( PageFactory.getStatus() != PageFactory.Status.FINISH){ return true; }*/ int x = (int)event.getX(); int y = (int)event.getY(); mAnimationProvider.setTouchPoint(x,y); if (event.getAction() == MotionEvent.ACTION_DOWN){ //mAnimationProvider.setCancel(false); https://github.com/PeachBlossom/treader/issues/4 downX = (int) event.getX(); downY = (int) event.getY(); moveX = 0; moveY = 0; isMove = false; // cancelPage = false; noNext = false; isNext = false; isRuning = false; mAnimationProvider.setStartPoint(downX,downY); abortAnimation(); mAnimationProvider.setCancel(false); //Log.e(TAG,"ACTION_DOWN"); }else if (event.getAction() == MotionEvent.ACTION_MOVE){ final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop(); //判断是否移动了 if (!isMove) { isMove = Math.abs(downX - x) > slop || Math.abs(downY - y) > slop; } Log.d(TAG, String.format("onTouchEvent:ACTION_MOVE isMove %s, isbusy %s",isMove,PageFactory.busy())); if(!PageFactory.busy()) if (isMove){ isMove = true; mTouchListener.hideAdBeforeIni() ; if (moveX == 0 && moveY ==0) { //Log.e(TAG,"isMove"); //判断翻得是上一页还是下一页 if (x - downX >0){ isNext = false; }else{ isNext = true; } cancelPage = false; if (isNext) { Boolean isNext = mTouchListener.nextPage(); // calcCornerXY(downX,mScreenHeight); mAnimationProvider.setDirection(AnimationProvider.Direction.next); if (!isNext) { noNext = true; return true; } } else { Boolean isPre = mTouchListener.prePage(); mAnimationProvider.setDirection(AnimationProvider.Direction.pre); if (!isPre) { noNext = true; return true; } } //Log.e(TAG,"isNext:" + isNext); }else{ //判断是否取消翻页 if(mTouchListener.canCancel()) { if (isNext) { if (x - moveX > 0) { cancelPage = true; mAnimationProvider.setCancel(true); } else { cancelPage = false; mAnimationProvider.setCancel(false); } } else { if (x - moveX < 0) { mAnimationProvider.setCancel(true); cancelPage = true; } else { mAnimationProvider.setCancel(false); cancelPage = false; } } }else{ noNext=true; } // if(cancelPage) //Log.e(TAG,"cancelPage:" + cancelPage); } moveX = x; moveY = y; isRuning = true; this.postInvalidate(); } }else if (event.getAction() == MotionEvent.ACTION_UP){ //Log.e(TAG,"ACTION_UP"); Log.d(TAG, String.format("onTouchEvent:ACTION_UP isMove %s, isbusy %s",isMove,PageFactory.busy())); if (!isMove || PageFactory.busy()){ cancelPage = false; //是否点击了中间 if (downX > mScreenWidth / 3 && downX < mScreenWidth * 2 / 3 && downY > mScreenHeight / 3 && downY < mScreenHeight * 2 / 3 ){ if (mTouchListener != null){ mTouchListener.center(); } //Log.e(TAG,"center"); // mCornerX = 1; // 拖拽点对应的页脚 // mCornerY = 1; // mTouch.x = 0.1f; // mTouch.y = 0.1f; return true; } else if (x < mScreenWidth / 2){ isNext = false; }else{ isNext = true; } if (isNext) { Boolean isNext = mTouchListener.nextPage(); mAnimationProvider.setDirection(AnimationProvider.Direction.next); if (!isNext) { return true; } } else { Boolean isPre = mTouchListener.prePage(); mAnimationProvider.setDirection(AnimationProvider.Direction.pre); if (!isPre) { return true; } } } if(!PageFactory.busy()) { if (cancelPage && mTouchListener != null) { mTouchListener.cancel(); } //Log.e(TAG, "isNext:" + isNext); if (!noNext) { isRuning = true; mAnimationProvider.startAnimation(mScroller); mTouchListener.showAdAfterIni(); this.postInvalidate(); } } } return true; } @Override public void computeScroll() { if (mScroller.computeScrollOffset()) { float x = mScroller.getCurrX(); float y = mScroller.getCurrY(); mAnimationProvider.setTouchPoint(x,y); if (mScroller.getFinalX() == x && mScroller.getFinalY() == y){ isRuning = false; } postInvalidate(); } super.computeScroll(); } public void abortAnimation() { if (!mScroller.isFinished()) { mScroller.abortAnimation(); mAnimationProvider.setTouchPoint(mScroller.getFinalX(),mScroller.getFinalY()); postInvalidate(); } } public boolean isRunning(){ return isRuning; } public void setTouchListener(TouchListener mTouchListener){ this.mTouchListener = mTouchListener; } public interface TouchListener{ void center(); Boolean prePage(); Boolean nextPage(); void cancel(); Boolean canCancel(); void showAdAfterIni(); void hideAdBeforeIni(); } }