Android GestureDetector 总结
来源:互联网 发布:淘宝会员无线端装修 编辑:程序博客网 时间:2024/05/22 03:42
- GestureDetector & OnTouchListener 区别
OnTouchListener 实现了如触摸屏相关的事件
OnGestureListener实现了 手势相关的事件
首先看OnTouchListener
Class 结构:
我们可以看出里面的概要方法有一个onTouch 方法这个方法就是我们需要实现的一个方法,
Called when a touch event is dispatched to a view.
一个触摸事件调用时被分配到一个视图中。从而实现对触摸时间的监听
例子:
public class Main3 extends Activity implements View.OnTouchListener{ private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); //监听这个ImageView组件上的触摸屏时间 image.setOnTouchListener(this); } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_UP: Log.e("ACTION_UP","Touch" +event.getAction()); break; case MotionEvent.ACTION_DOWN: Log.e("ACTION_DOWN","Touch" +event.getAction()); break; case MotionEvent.ACTION_MOVE: Log.e("ACTION_MOVE","Touch" +event.getAction()); break; } return true; } }
我们可以通过MotionEvent的getAction()方法来获取Touch事件的类型,包括 ACTION_DOWN(按下触摸屏), ACTION_MOVE(按下触摸屏后移动受力点), ACTION_UP(松开触摸屏)和ACTION_CANCEL(不会由用户直接触发)。借助对于用户不同操作的判断,结合getRawX()、 getRawY()、getX()和getY()等方法来获取坐标后,我们可以实现诸如拖动某一个按钮,拖动滚动条等功能。
可以看到OnTouchListener只能监听到三种触摸事件,即按下,移动,松开,如果想要监听到双击、滑动、长按等复杂的手势操作,这个时候就必须得用到OnGestureListener了。
接下来是OnGestureListener
结构图:
OnGestureListener 里面的方法
onDown // 用户轻触触摸屏
OnFling // 用户快速抛掷
OnLongPress // 用户长按触摸屏
OnScroll // 用户按下触摸屏,并拖动
OnShowPrees // 用户轻触触摸屏,尚未松开或拖动
OnSingleTapup // 用户(轻触触摸屏后)松开
这里有疑问了,我们ontouch 是通过设置他的监听事件来运行的,可是Gesture 里面并没有找到这个设置事件呢?还是可以在文档中找到的
文档中说是需要在Ontouch的监听 里面 调用 他的 onTouchEvent 事件这样就可以监听手势了
例子:
public class Main3 extends Activity implements View.OnTouchListener, GestureDetector.OnGestureListener { private ImageView image; private GestureDetector mGestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); //监听这个ImageView组件上的触摸屏时间 image.setOnTouchListener(this); // mGestureDetector = new GestureDetector(this); // // GestureDetector的构造函数在4.1版本中已经过时,可以使用推荐的: // 注意前一个this代表的是一个Context,后一个this代表的是一个OnGestureListener。 // Activity继承自Context, 而你的activity应该实现了(implements)OnGestureListener接口。 mGestureDetector = new GestureDetector(this, this); } @Override public boolean onTouch(View v, MotionEvent event) {// switch (event.getAction()){// case MotionEvent.ACTION_UP:// Log.e("ACTION_UP","Touch" +event.getAction());// break;// case MotionEvent.ACTION_DOWN:// Log.e("ACTION_DOWN","Touch" +event.getAction());// break;// case MotionEvent.ACTION_MOVE:// Log.e("ACTION_MOVE","Touch" +event.getAction());// break;//// }//// return true; return mGestureDetector.onTouchEvent(event); } // 用户轻触触摸屏 @Override public boolean onDown(MotionEvent e) { Log.e("MyGesture", "onDown"); return true; } // 用户轻触触摸屏,尚未松开或拖动 @Override public void onShowPress(MotionEvent e) { Log.e("MyGesture", "onShowPress"); } // 用户(轻触触摸屏后)松开, @Override public boolean onSingleTapUp(MotionEvent e) { Log.e("MyGesture", "onSingleTapUp"); return true; } // 用户按下触摸屏,并拖动 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.e("MyGesture", "onScroll"); return true; } // 用户长按触摸屏 @Override public void onLongPress(MotionEvent e) { Log.e("MyGesture", "onLongPress"); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.e("MyGesture", "onFling"); return true; }}
下面是几个方法的调用顺序:
长按
10-16 16:05:45.319 10496-10496/? E/MyGesture﹕ onDown
10-16 16:05:45.489 10496-10496/? E/MyGesture﹕ onShowPress
10-16 16:05:45.999 10496-10496/? E/MyGesture﹕ onLongPress
轻触
10-16 16:06:10.479 10496-10496/? E/MyGesture﹕ onDown
10-16 16:06:10.549 10496-10496/? E/MyGesture﹕ onSingleTapUp
拖动
10-16 16:06:35.709 10496-10496/? E/MyGesture﹕ onDown
10-16 16:06:36.469 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:06:36.489 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:06:36.499 10496-10496/? E/MyGesture﹕ onScroll
抛掷
10-16 16:07:15.249 10496-10496/? E/MyGesture﹕ onDown
10-16 16:07:15.359 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:07:15.379 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:07:15.389 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:07:15.409 10496-10496/? E/MyGesture﹕ onScroll
10-16 16:07:15.419 10496-10496/? E/MyGesture﹕ onFling
(1)MotionEvent中 e1是手指第一次按上屏幕的起点,e2是抬起手指离开屏幕的终点,根据上图Android屏幕坐标系可知:
手指向右滑动,终点(e2)在起点(e1)的右侧,有e2.getX() - e1.getX() 大于0 手指向左滑动,终点(e2)在起点(e1)的左侧,有e2.getX() - e1.getX() 小于0 手指向下滑动,终点(e2)在起点(e1)的下侧,有e2.getY() - e1.getY() 大于0 手指向上滑动,终点(e2)在起点(e1)的上侧,有e2.getY() - e1.getY() 小于0
(2)onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
distanceX,是前后两次call的X距离,不是e2与e1的水平距离 distanceX,是前后两次call的Y距离,不是e2与e1的垂直距离 具体数值的方向,请详见上图(中)
(3)onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
velocityX,是X轴的每秒速度 velocityY,是Y轴的每秒速度 具体数值的方向,请详见上图(右) 仔细观察可以发现:velocityX、velocityY的方向与distanceX、distanceY方向正好相反
- GestureDetector 内容方法
下面是GestureDetector 的具体使用方法,使用抛掷做的一个切换界面的demo,判断了四个方向的手势。
public class MainActivity extends Activity implements View.OnTouchListener, GestureDetector.OnGestureListener { //创建一个用于识别手势 的GestureDetecttor 对象 private GestureDetector detector = new GestureDetector(this); //定义一个数组,用于放漂亮的女孩 int[] girls = new int[]{R.drawable.girl1, R.drawable.girl2, R.drawable.girl3}; //定义数组下标,以方便观看各个女孩 private int index; private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); //设置一个初始显示的girl吧 image.setImageResource(girls[index]); //监听这个ImageView组件上的触摸屏时间 image.setOnTouchListener(this); //下面两个要记得设哦,不然就没法处理轻触以外的事件了,例如抛掷动作。 image.setLongClickable(true); detector.setIsLongpressEnabled(true); } //用于呼喊下一个女孩的方法 public void goNext() { index++; index = Math.abs(index % girls.length); image.setImageResource(girls[index]); } //用户呼唤上一个女孩的方法 public void goPrevious() { index--; index = Math.abs(index % girls.length); image.setImageResource(girls[index]); } //此方法在触摸屏被触摸,即发生触摸事件(接触和抚摸两个事件,挺形象)的时候被调用。 @Override public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } //在抬起时被调用 @Override public boolean onSingleTapUp(MotionEvent e) { return false; } //在按住时被调用 @Override public void onShowPress(MotionEvent e) { } //在滚动时调用 @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } //在长按时被调用 @Override public void onLongPress(MotionEvent e) { }// 在抛掷动作时被调用// @Override// public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {//// //velocityX表示横向的移动,根据手指移动的方向切换女孩// Log.e("x",velocityX+"");// Log.e("y",velocityY+"");//// if (velocityX < 300) {// goNext();// } else if (velocityX > 300) {// goPrevious();// }// return false;// } private DisplayMetrics getscreen(){ DisplayMetrics dm = new DisplayMetrics(); this.getWindowManager().getDefaultDisplay().getMetrics(dm); return dm; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { //这个可以判断 上下左右的四个手势动作 float x = e2.getX() - e1.getX(); float y = e2.getY() - e1.getY(); // 限制必须得划过屏幕的1/4才能算划过 float x_limit = getscreen().widthPixels / 4; float y_limit = getscreen().heightPixels / 4; float x_abs = Math.abs(x); float y_abs = Math.abs(y); if (x_abs >= y_abs) { // gesture left or right if (x > x_limit || x < -x_limit) { if (x > 0) { // right Log.e("Tag", "right"); startActivity(new Intent(this,Main2.class)); } else if (x <= 0) { // left startActivity(new Intent(this,Main3.class)); Log.e("Tag", "left"); } } } else { // gesture down or up if (y > y_limit || y < -y_limit) { if (y > 0) { // down Log.e("Tag", "down"); } else if (y <= 0) { // up Log.e("Tag", "up"); } } } Log.e("Tag", "判断结束"); return true; } //在按下动作时被调用 @Override public boolean onDown(MotionEvent e) { return false; }}
GestureDetector 中SimpleOnScaleGestureListener&SimpleOnGestureListener 用法
If you only want to listen for a subset it might be easier to extend GestureDetector.SimpleOnGestureListener.
官方推荐一个更简易,更建议使用的一个已实现的方法
适用于单一手势
下面是例子:
public class Main2 extends Activity implements View.OnTouchListener { private GestureDetector gestureDetector; //手势探测器 private ScaleGestureDetector ScaleGesture;//比率手势探测器 private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image); //监听这个ImageView组件上的触摸屏时间 image.setOnTouchListener(this); gestureDetector = new GestureDetector(this, new DefGesture()); ScaleGesture = new ScaleGestureDetector(this,new ScaleGesture()); } @Override public boolean onTouch(View v, MotionEvent event) { gestureDetector.onTouchEvent(event); ScaleGesture.onTouchEvent(event); return true; //true 代表可以分发 false 不可以分发 }}class DefGesture extends GestureDetector.SimpleOnGestureListener { @Override public boolean onDoubleTap(MotionEvent e) { Log.e("onDoubleTap", e.getAction() + ""); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.e("onDoubleTapEvent", e.getAction() + ""); return super.onDoubleTapEvent(e); }}//SimpleOnScaleGestureListener implements OnScaleGestureListenerclass ScaleGesture extends ScaleGestureDetector.SimpleOnScaleGestureListener {//双手指操作 @Override public boolean onScale(ScaleGestureDetector detector) { detector.getCurrentSpan();//两点间的距离跨度 detector.getCurrentSpanX();//两点间的x距离 detector.getCurrentSpanY();//两点间的y距离 detector.getFocusX(); // detector.getFocusY(); // detector.getPreviousSpan(); //上次 detector.getPreviousSpanX();//上次 detector.getPreviousSpanY();//上次 detector.getEventTime(); //当前事件的事件 detector.getTimeDelta(); //两次事件间的时间差 detector.getScaleFactor(); //与上次事件相比,得到的比例因子 Log.e("getCurrentSpan", detector.getCurrentSpan() + ""); return true; }}
代码下载地址:http://download.csdn.net/detail/v7428477/9187225
- Android小总结:GestureDetector
- Android GestureDetector 总结
- Android GestureDetector
- Android GestureDetector
- Android - GestureDetector
- Android中手势滑动翻页之GestureDetector总结
- Android图片处理总结三:(图片手势控制)GestureDetector解析
- Android GestureDetector手势识别
- Android 浅析GestureDetector
- Android 浅析GestureDetector
- android 手势操作GestureDetector
- Android GestureDetector 手势基础
- Android GestureDetector 手势基础
- android.view.GestureDetector类
- android GestureDetector应用
- android 手势操作GestureDetector
- Android GestureDetector 手势基础
- Android 浅析GestureDetector
- android 弹窗
- matlab中由size函数引发的问题
- 20151014星号三角阵(四种)
- hihocoder 1097 : 最小生成树一·Prim算法
- php删除指定文件夹下的所有文件
- Android GestureDetector 总结
- CentOS 7安装配置Samba服务器
- 第十章 内部类(下)
- iOS之巅峰 imageView 和 Label的点击事件
- 【Android应用场景】Android开发邮箱APP(二)
- java list问题
- zabbix
- 使用ssh 访问越狱iPhone的两种方式
- cocos2d中的ui和事件机制