Android电子书翻页和手指缩放的实现

来源:互联网 发布:物理层算法 招聘 编辑:程序博客网 时间:2024/05/02 10:24

             

项目间隙研究了下PDF阅读器的代码,发现大部分源码都提供了翻页效果,而没有实现支持翻页的同时支持缩放的效果。下面给出实现的方案。有问题欢迎交流。

        实现的整体思路是这样的。在一个相对布局中有两个自定义的view,一个用来翻页,一个用来缩放。初始化载入缩放的View,对这个View进行监听,这里坐了三种监听,翻页监听、缩放监听、点击监听。监听到翻页的时候,启用翻页View的回调,传给翻页View滑动开始的坐标值,然后交换View视图,即翻页View显示,缩放View隐藏。然后开始处理翻页的逻辑。翻页成功后置成初始化成功时的状态。下面贴一下核心代码。

       翻页的自定义View用的开源的例子,主要原理就是贝塞尔曲线。这里就不再贴出来了。下面主要介绍下缩放的自定义View。

      

 setOnTouchListener(new OnTouchListener() {            @Override            public boolean onTouch(View v, MotionEvent event) {                mScaleDetector.onTouchEvent(event);                PointF curr = new PointF(event.getX(), event.getY());                              switch (event.getAction()) {                //判断手指的手势操作,这里为缩放模式                    case MotionEvent.ACTION_POINTER_DOWN:                                                last.set(curr);                        start.set(last);                        mode = ZOOM;                        isInClickArea = false;                                            break;                    case MotionEvent.ACTION_DOWN:                     //判断是否为缩放模式,如果saveScale比1大,就认为是缩放模式了。                     if(saveScale - 1 > 0.001){                                          mode = ZOOM;                     last.set(curr);                             start.set(last);                                          }else{//拖拽模式                     mode = DRAG;                     int x = (int) event.getX();                     //下面这段代码是用来处理点击事件的,onTouch事件会劫持onClick事件,所以这里如果down的坐标                     //在屏幕的中间,这里定义的中间为屏幕三分之后的中间位置。返回false,自定义View就会响应onClick事件      if(x > (Config.SCREEN_WIDTH/3) && x < (Config.SCREEN_WIDTH*2/3)){           isInClickArea = true;           return false;      }      isInClickArea = false;                             mode = DRAG;                                                  downX = (int) event.getX();                     downY = (int) event.getY();                     mPagerListenr.pager(event);                     startTime = System.nanoTime();                     }                                                              break;                                           case MotionEvent.ACTION_MOVE:                                            if (mode == ZOOM || saveScale - 1 > 0.001) {                            float deltaX = curr.x - last.x;                            float deltaY = curr.y - last.y;                            float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);                                                        float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);                            matrix.postTranslate(fixTransX, fixTransY);                            fixTrans();                            last.set(curr.x, curr.y);                        }else if(mode == DRAG){                                                 if(isInClickArea){    return false;     }                         moveX = (int) event.getX();                     moveY = (int) event.getY();                     //回调函数                     mPagerListenr.pagerNext(event);                                            }                        break;                    case MotionEvent.ACTION_UP:                                        firstMove = true;                                              if(mode == DRAG ){                         if(isInClickArea){    return false;     }                         mode = NONE;                         //执行回调函数                         return mPagerListenr.pagerNext(event);                                                }                           mode = NONE;                        reScale();                                               break;                    case MotionEvent.ACTION_POINTER_UP:                                         firstMove = true;                    if(mode == DRAG){                    mode = NONE;                    //执行回调函数                         return mPagerListenr.pagerNext(event);                        }                    mode = NONE;                        reScale();                                               break;                }                            setImageMatrix(matrix);                                 invalidate();                return true;                               }                    });        setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v) {// TODO Auto-generated method stubmPagerListenr.onClick();}                });

         

 public interface PagerListener{        public void pager(MotionEvent event);                public boolean pagerNext(MotionEvent event);                public boolean onLongClick();                public void onClick();    }       private PagerListener mPagerListenr;    public void setOnPagerListener(PagerListener mPagerListenr){    this.mPagerListenr = mPagerListenr;    }
      以上代码都是在自定义的View中,这个View继承自ImageView。

      下面看下Activity的逻辑代码。

      

private void initPageImg(){    pageImg = (TouchImageView) findViewById(R.id.img_pageview);    pageImg.setImageBitmap(mCurPageBitmap);    pageImg.setMaxZoom(4f);    pageImg.setOnPagerListener(new PagerListener() {@Overridepublic boolean onLongClick() {// ���ﴦ�?���¼�// TODO Auto-generated method stub//handleLongPressOnPageView();return false;}@Overridepublic void pager(MotionEvent event) {// TODO Auto-generated method stub// if (event.getAction() == MotionEvent.ACTION_DOWN) {mPager.abortAnimation();mPager.calcCornerXY(event.getX(), event.getY());// ��������滻bitmapif (mPager.DragToRight()) {// ���һ�������ʾǰһҳif (pageNum == 0) {return;} else {mCurPageBitmap = getBitmapByPageNo(pageNum);mNextPageBitmap = mCurPageBitmap;pageNum--;mCurPageBitmap = getBitmapByPageNo(pageNum);}} else {// ���

                  大致就是这样子,需要源码的可以留下联系方式,有问题欢迎交流。




原创粉丝点击