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

 public abstract class VersionedGestureDetector {
static final String LOG_TAG = "VersionedGestureDetector";
OnGestureListener mListener; public static VersionedGestureDetector newInstance(Context context, OnGestureListener listener) {
final int sdkVersion = Build.VERSION.SDK_INT;
VersionedGestureDetector detector = null;
if (sdkVersion < Build.VERSION_CODES.ECLAIR) {
detector = new CupcakeDetector(context);
} else if (sdkVersion < Build.VERSION_CODES.FROYO) {
detector = new EclairDetector(context);
} else {
detector = new FroyoDetector(context);
} detector.mListener = listener; return detector;
} public abstract boolean onTouchEvent(MotionEvent ev); public abstract boolean isScaling(); public static interface OnGestureListener {
public void onDrag(float dx, float dy); public void onFling(float startX, float startY, float velocityX, float velocityY); public void onScale(float scaleFactor, float focusX, float focusY);
} // <2.0
private static class CupcakeDetector extends VersionedGestureDetector { float mLastTouchX;
float mLastTouchY;
final float mTouchSlop;
final float mMinimumVelocity; public CupcakeDetector(Context context) {
final ViewConfiguration configuration = ViewConfiguration.get(context);
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mTouchSlop = configuration.getScaledTouchSlop();
} private VelocityTracker mVelocityTracker;
private boolean mIsDragging; float getActiveX(MotionEvent ev) {
return ev.getX();
} float getActiveY(MotionEvent ev) {
return ev.getY();
} public boolean isScaling() {
return false;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN: {
mVelocityTracker = VelocityTracker.obtain();
mVelocityTracker.addMovement(ev); mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev);
mIsDragging = false;
break;
}
case MotionEvent.ACTION_MOVE: {
final float x = getActiveX(ev);
final float y = getActiveY(ev);
final float dx = x - mLastTouchX, dy = y - mLastTouchY; if (!mIsDragging) {
// Use Pythagoras to see if drag length is larger than
// touch slop
mIsDragging = FloatMath.sqrt((dx * dx) + (dy * dy)) >= mTouchSlop;
} if (mIsDragging) {
mListener.onDrag(dx, dy);
mLastTouchX = x;
mLastTouchY = y; if (null != mVelocityTracker) {
mVelocityTracker.addMovement(ev);
}
}
break;
} case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: {
if (mIsDragging) {
mIsDragging = false; if (null != mVelocityTracker) {
mLastTouchX = getActiveX(ev);
mLastTouchY = getActiveY(ev); // Compute velocity within the last 1000ms
mVelocityTracker.addMovement(ev);
mVelocityTracker.computeCurrentVelocity(1000); final float vX = mVelocityTracker.getXVelocity(), vY = mVelocityTracker.getYVelocity(); // If the velocity is greater than minVelocity, call
// listener
if (Math.max(Math.abs(vX), Math.abs(vY)) >= mMinimumVelocity) {
mListener.onFling(mLastTouchX, mLastTouchY, -vX, -vY);
}
}
} // Recycle Velocity Tracker
if (null != mVelocityTracker) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
}
return true;
}
} // =2.0 =2.1
private static class EclairDetector extends CupcakeDetector {
private static final int INVALID_POINTER_ID = -1;
private int mActivePointerId = INVALID_POINTER_ID;
private int mActivePointerIndex = 0; public EclairDetector(Context context) {
super(context);
} @Override
float getActiveX(MotionEvent ev) {
try {
return ev.getX(mActivePointerIndex);
} catch (Exception e) {
return ev.getX();
}
} @Override
float getActiveY(MotionEvent ev) {
try {
return ev.getY(mActivePointerIndex);
} catch (Exception e) {
return ev.getY();
}
} @Override
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
mActivePointerId = INVALID_POINTER_ID;
break;
case MotionEvent.ACTION_POINTER_UP:
final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
final int pointerId = ev.getPointerId(pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = ev.getPointerId(newPointerIndex);
mLastTouchX = ev.getX(newPointerIndex);
mLastTouchY = ev.getY(newPointerIndex);
}
break;
} mActivePointerIndex = ev.findPointerIndex(mActivePointerId != INVALID_POINTER_ID ? mActivePointerId : 0);
return super.onTouchEvent(ev);
}
} // >=2.2 add a ScaleGestureDetector
private static class FroyoDetector extends EclairDetector implements ScaleGestureDetector.OnScaleGestureListener {
private ScaleGestureDetector mDetector; public FroyoDetector(Context context) {
super(context);
mDetector = new ScaleGestureDetector(context, this);
} @Override
public boolean isScaling() {
return mDetector.isInProgress();
} @Override
public boolean onScale(ScaleGestureDetector detector) {
mListener.onScale(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
return true;
} @Override
public boolean onTouchEvent(MotionEvent ev) {
mDetector.onTouchEvent(ev);
return super.onTouchEvent(ev);
} @Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
return true;
} @Override
public void onScaleEnd(ScaleGestureDetector detector) {
// NO-OP
}
}
}

Android VersionedGestureDetector手势事件的更多相关文章

  1. Qt for android触摸手势事件QGestureEvent

    在触摸设备上可以使用Qt的手势事件 要激活手势事件,需要执行以下操作: 第一步,为QWidget控件注册手势事件 QList<Qt::GestureType> gestures; gest ...

  2. surface上的手势事件

    surface上的手势事件 1.surface上的触控事件测试. 手指触控在CHROME和FIREFOX下会触发touch事件,而IE10是不支持touch事件的. 手指触控在三个浏览器下均会触发全部 ...

  3. Android 触摸手势基础 官方文档概览

    Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...

  4. android GestureDetector 手势基础

    1. 当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(Vi ...

  5. Android 触摸手势基础 官方文档概览2

    Android 触摸手势基础 官方文档概览 触摸手势检测基础 手势检测一般包含两个阶段: 1.获取touch事件数据 2.解析这些数据,看它们是否满足你的应用所支持的某种手势. 相关API: Moti ...

  6. JavaScript触摸与手势事件

    JavaScript触摸与手势事件 发表于 2012-12-10 由 admin iOS版Safari为了向开发人员传达一些特殊信息,新增了一些专有事件.因为iOS设备既没有鼠标也没有键盘,所以在为移 ...

  7. Javascript高级编程学习笔记(69)—— 事件(13)触摸与手势事件

    触摸与手势事件 由于移动设备既没有鼠标也没有键盘,所以在为移动浏览器开发交互性网页时,常规的鼠标键盘事件根本不够用 所以早期的苹果为Safari 添加了一些与触摸相关的事件 随着后面Android的W ...

  8. Android View 的事件分发原理解析

    作为一名 Android 开发者,每天接触最多的就是 View 了.Android View 虽然不是四大组件,但其并不比四大组件的地位低.而 View 的核心知识点事件分发机制则是不少刚入门同学的拦 ...

  9. Android触碰事件

    OnTouchListener使用 public class ViewActivity extends Activity implements View.OnTouchListener { @Over ...

随机推荐

  1. spring.hibernate设置参数的位置问题

    1.spring的注解设置在set方法上 2.hibernate的注解设置在get方法上

  2. 转载 - LINUX下查看CPU使用率的命令

    几个常用的命令,一些不错的解释 http://blog.csdn.net/wengpingbo/article/details/6302058 1.top 使用权限:所有使用者 使用方式:top [- ...

  3. 转 java int与Integer的区别

    int是java提供的8种原始数据类型之一, Java为每个原始类型提供了封装类,Integer是java为int提供的封装类. int 是基本类型,Integer是引用类型. java.lang.I ...

  4. android中textview设置为多行文本时,如何让文字从最顶开始显示

    <span style="white-space:pre"> </span><EditText android:layout_width=" ...

  5. bzoj题解汇总(1032~1051)

    bzoj1034:贪心 bzoj1036:树剖 bzoj1037:一个比较巧妙,利用连续性维护的dp. http://www.cnblogs.com/Sdchr/p/6129496.html bzoj ...

  6. 关于GET请求带Body的问题

    今天在进行接口联调时遇到这个问题了,当时是很茫然的,因为从来没遇过. 后来又搜索了一下GET和Post的区别. 然后看见了这篇文章.不再以讹传讹,GET和POST的真正区别 我有限的知识还是无法去确定 ...

  7. HTML5自学笔记[ 1 ]新增标签

    新增语义化标签 <header></header>: 用于页面或板块头部. <footer></footer>:用于页面底部. <nav>& ...

  8. AES算法

    高级加密标准(Advanced Encryption Standard,AES),又称 高级加密标准Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多 ...

  9. JQ添加移除css样式

    1. addClass() - 添加CSS类 $("#target").addClass("newClass"); //#target 指的是需要添加样式的元素 ...

  10. 【转载】Gambit使用教程

    第一章 Gambit使用 Gambit介绍 网格的划分使用Gambit软件,首先要启动Gambit,在Dos下输入Gambit <filemane>,文件名如果已经存在,要加上参数-old ...