356 lines
13 KiB
Plaintext
356 lines
13 KiB
Plaintext
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();
|
|
}
|
|
|
|
}
|