zoukankan      html  css  js  c++  java
  • Android VersionedGestureDetector手势事件

      今天研究了一下PhotoView,发现里面的自定义的手势事件可以支持所有的SDK版本,该事件可以实现拖拽、滑动、缩放功能。下面直接上代码:

      1 public abstract class VersionedGestureDetector {
      2     static final String LOG_TAG = "VersionedGestureDetector";
      3     OnGestureListener mListener;
      4 
      5     public static VersionedGestureDetector newInstance(Context context, OnGestureListener listener) {
      6         final int sdkVersion = Build.VERSION.SDK_INT;
      7         VersionedGestureDetector detector = null;
      8         if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
      9             detector = new CupcakeDetector(context);
     10         } else if (sdkVersion < Build.VERSION_CODES.FROYO) {
     11             detector = new EclairDetector(context);
     12         } else {
     13             detector = new FroyoDetector(context);
     14         }
     15 
     16         detector.mListener = listener;
     17 
     18         return detector;
     19     }
     20 
     21     public abstract boolean onTouchEvent(MotionEvent ev);
     22 
     23     public abstract boolean isScaling();
     24 
     25     public static interface OnGestureListener {
     26         public void onDrag(float dx, float dy);
     27 
     28         public void onFling(float startX, float startY, float velocityX, float velocityY);
     29 
     30         public void onScale(float scaleFactor, float focusX, float focusY);
     31     }
     32 
     33     // <2.0 
     34     private static class CupcakeDetector extends VersionedGestureDetector {
     35 
     36         float mLastTouchX;
     37         float mLastTouchY;
     38         final float mTouchSlop;
     39         final float mMinimumVelocity;
     40 
     41         public CupcakeDetector(Context context) {
     42             final ViewConfiguration configuration = ViewConfiguration.get(context);
     43             mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
     44             mTouchSlop = configuration.getScaledTouchSlop();
     45         }
     46 
     47         private VelocityTracker mVelocityTracker;
     48         private boolean mIsDragging;
     49 
     50         float getActiveX(MotionEvent ev) {
     51             return ev.getX();
     52         }
     53 
     54         float getActiveY(MotionEvent ev) {
     55             return ev.getY();
     56         }
     57 
     58         public boolean isScaling() {
     59             return false;
     60         }
     61 
     62         @Override
     63         public boolean onTouchEvent(MotionEvent ev) {
     64             switch (ev.getAction()) {
     65                 case MotionEvent.ACTION_DOWN: {
     66                     mVelocityTracker = VelocityTracker.obtain();
     67                     mVelocityTracker.addMovement(ev);
     68 
     69                     mLastTouchX = getActiveX(ev);
     70                     mLastTouchY = getActiveY(ev);
     71                     mIsDragging = false;
     72                     break;
     73                 }
     74                 case MotionEvent.ACTION_MOVE: {
     75                     final float x = getActiveX(ev);
     76                     final float y = getActiveY(ev);
     77                     final float dx = x - mLastTouchX, dy = y - mLastTouchY;
     78 
     79                     if (!mIsDragging) {
     80                         // Use Pythagoras to see if drag length is larger than
     81                         // touch slop
     82                         mIsDragging = FloatMath.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
     83                     }
     84 
     85                     if (mIsDragging) {
     86                         mListener.onDrag(dx, dy);
     87                         mLastTouchX = x;
     88                         mLastTouchY = y;
     89 
     90                         if (null != mVelocityTracker) {
     91                             mVelocityTracker.addMovement(ev);
     92                         }
     93                     }
     94                     break;
     95                 }
     96 
     97                 case MotionEvent.ACTION_CANCEL:
     98                 case MotionEvent.ACTION_UP: {
     99                     if (mIsDragging) {
    100                         mIsDragging = false;
    101 
    102                         if (null != mVelocityTracker) {
    103                             mLastTouchX = getActiveX(ev);
    104                             mLastTouchY = getActiveY(ev);
    105 
    106                             // Compute velocity within the last 1000ms
    107                             mVelocityTracker.addMovement(ev);
    108                             mVelocityTracker.computeCurrentVelocity(1000);
    109 
    110                             final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker.getYVelocity();
    111 
    112                             // If the velocity is greater than minVelocity, call
    113                             // listener
    114                             if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
    115                                 mListener.onFling(mLastTouchX, mLastTouchY, -vX, -vY);
    116                             }
    117                         }
    118                     }
    119 
    120                     // Recycle Velocity Tracker
    121                     if (null != mVelocityTracker) {
    122                         mVelocityTracker.recycle();
    123                         mVelocityTracker = null;
    124                     }
    125                     break;
    126                 }
    127             }
    128             return true;
    129         }
    130     }
    131 
    132     // =2.0 =2.1
    133     private static class EclairDetector extends CupcakeDetector {
    134         private static final int INVALID_POINTER_ID = -1;
    135         private int mActivePointerId = INVALID_POINTER_ID;
    136         private int mActivePointerIndex = 0;
    137 
    138         public EclairDetector(Context context) {
    139             super(context);
    140         }
    141 
    142         @Override
    143         float getActiveX(MotionEvent ev) {
    144             try {
    145                 return ev.getX(mActivePointerIndex);
    146             } catch (Exception e) {
    147                 return ev.getX();
    148             }
    149         }
    150 
    151         @Override
    152         float getActiveY(MotionEvent ev) {
    153             try {
    154                 return ev.getY(mActivePointerIndex);
    155             } catch (Exception e) {
    156                 return ev.getY();
    157             }
    158         }
    159 
    160         @Override
    161         public boolean onTouchEvent(MotionEvent ev) {
    162             final int action = ev.getAction();
    163             switch (action & MotionEvent.ACTION_MASK) {
    164                 case MotionEvent.ACTION_DOWN:
    165                     mActivePointerId = ev.getPointerId(0);
    166                     break;
    167                 case MotionEvent.ACTION_CANCEL:
    168                 case MotionEvent.ACTION_UP:
    169                     mActivePointerId = INVALID_POINTER_ID;
    170                     break;
    171                 case MotionEvent.ACTION_POINTER_UP:
    172                     final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
    173                     final int pointerId = ev.getPointerId(pointerIndex);
    174                     if (pointerId == mActivePointerId) {
    175                         // This was our active pointer going up. Choose a new
    176                         // active pointer and adjust accordingly.
    177                         final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
    178                         mActivePointerId = ev.getPointerId(newPointerIndex);
    179                         mLastTouchX = ev.getX(newPointerIndex);
    180                         mLastTouchY = ev.getY(newPointerIndex);
    181                     }
    182                     break;
    183             }
    184 
    185             mActivePointerIndex = ev.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId : 0);
    186             return super.onTouchEvent(ev);
    187         }
    188     }
    189 
    190     // >=2.2 add a ScaleGestureDetector
    191     private static class FroyoDetector extends EclairDetector implements ScaleGestureDetector.OnScaleGestureListener {
    192         private ScaleGestureDetector mDetector;
    193 
    194         public FroyoDetector(Context context) {
    195             super(context);
    196             mDetector = new ScaleGestureDetector(context, this);
    197         }
    198 
    199         @Override
    200         public boolean isScaling() {
    201             return mDetector.isInProgress();
    202         }
    203 
    204         @Override
    205         public boolean onScale(ScaleGestureDetector detector) {
    206             mListener.onScale(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
    207             return true;
    208         }
    209 
    210         @Override
    211         public boolean onTouchEvent(MotionEvent ev) {
    212             mDetector.onTouchEvent(ev);
    213             return super.onTouchEvent(ev);
    214         }
    215 
    216         @Override
    217         public boolean onScaleBegin(ScaleGestureDetector detector) {
    218             return true;
    219         }
    220 
    221         @Override
    222         public void onScaleEnd(ScaleGestureDetector detector) {
    223             // NO-OP
    224         }
    225     }
    226 }
  • 相关阅读:
    Java知识汇总第二天
    jvm学习笔记
    java知识汇总的第一天
    全链路压测流量模型
    FunTester测试框架Redis性能测试实践
    FunTester抄代码之路
    Jira API的踩坑记
    把工作讲给家人听
    颇具年代感的《JMeter中文操作手册》
    FunTester框架Redis压测预备
  • 原文地址:https://www.cnblogs.com/phj981805903/p/3283004.html
Copyright © 2011-2022 走看看