今天研究了一下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. 【Linux系统】防暴力破解

    在日志文件/var/log/secure 中可以看到涉及到安全方面的日志,可以查看是否有人尝试暴力破解及是否成功,对于肉鸡行为有一定帮助 思路基本上都是加强密码的复杂度,增加iptables配置黑名单 ...

  2. css-高度自适应的问题(body高度问题)

    css-高度自适应的问题 对象height:100%并不能直接产生效果,是因为跟其父对象有关. #center{ height:100%; } 上面的css样式是无效的,不会产生任何效果. 需要改写: ...

  3. fushioncharts的使用教程

    FusionCharts 是使用javascript 实现统计图表的js组件:其官网地址:http://www.fusioncharts.com.其早期版本FusionCharts Free 是基于f ...

  4. 【bzoj1027】合金

    [bzoj1027]合金 分析 数形结合+计算几何+Floyd最小环. http://blog.csdn.net/popoqqq/article/details/40539273 虽然这样占大家的很不 ...

  5. echarts折线图--数据交互

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  6. CentOS 6.x启动时网卡eth0未激活

    简述 安装CentOS 6.x操作系统后,开机时发现没有网络,最后发现系统启动时未激活网卡 - 因为只有在激活状态的网卡才能去连接网络,进行网络通讯. 简述 激活网卡eth0 激活网卡eth0 执行& ...

  7. (14)odoo加载机制

    Odoo的启动通过openerp-server脚本完成,它是系统的入口. 然后加载配置文件openerp-server.conf 或者 .openerp_serverrc: openerp-serve ...

  8. 解决li在ie,firefox中行高不一致问题

    转载 http://www.cnblogs.com/jikey/archive/2011/11/13/2247543.html li在ie与firefox的高度是不一样的,解决办法是li font-s ...

  9. 189. Rotate Array -- 将数组前一半移到后一半

    Rotate an array of n elements to the right by k steps. For example, with n = 7 and k = 3, the array ...

  10. mvc伪静态<三> IIS配置

    上一篇已经已经讲述了mvc伪静态的代码实现. 下面以IIS 7.5为例演示一下IIS如何配置才能在服务器显示.html的伪静态 一.进入IIS,选择处理程序映射 二添加脚本映射 三根据你的处理程序的版 ...