Android GestureDetector详解
1. 事件监听的方法
在android应用层上主要有两个层面的触摸事件监听,一个是Activity
层,另一个是View
层。方法主要有三种:
第一是Activity
中重写父类中的public boolean onTouchEvent(MotionEvent event)
方法;
@Override
public boolean onTouchEvent(MotionEvent event) {return super.onTouchEvent(event);
}
第二个是重写View
类中的GestDetector.OnGestureListener
接口中定义的boolean onTouch(View v, MotionEvent event);
@Override
public boolean onTouch(View v, MotionEvent event) {return false;
}
第三个是利用GestureDetector.onTouchEvent(event)
在View.onTouch
方法中来接管事件处理
@Override
public boolean onTouch(View v, MotionEvent event) {return mGestureDetector.onTouchEvent(event);
}
当view
上的事件被分发到view
上时触发onTouch
方法的回调, 如果这个方法返回false
时,表示事件处理失败,该事件就会被传递给相应的Activity
中的onTouchEvent
方法来处理。
如果该方法返回true
时,表示该事件已经被onTouch
函数处理完,不会上传到activity
中处理。
2. GestureDector类
GestureDector
类需要注意以下内容:
OnGestureListener
接口OnDoubleTapListener
双击接口SimpleOnGestureListener
类(实现了类内的三个接口)onTouchEvent()
方法setOnDoubleTapListener()
双击监听
当屏幕上发生特定的触摸事件,就会去回调GestureDector.OnGestureListener
和GestureDetector.OnDoubleTapListener
接口中相应的回调函数来监测各样的手势和事件,并且通知用户。但是这些触发函数都没有具体的实现,我们必须实现这些接口,并重写这些方法的具体实现。
GestureDetector
类中已经为我们定义了一个静态内部类SimpleOnGestureListener
,它实现了OnGestureListener
,OnDoubleTapListener
,OnContextClickListener
接口,定义为
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,OnContextClickListener
SimpleOnGestureListener
类内重写接口中的所有方法,但是都是空实现,返回的布尔值都是false
。主要作用是方便我们继承这个类有选择的复写回调方法,而不是实现接口去重写所有的方法。
onTouchEvent()
方法用来分析传入的事件,如果匹配的话就去触发OnGestureListener
中相应的回调方法。
如果要监听双击事件必须调用GestureDector.setOnDoubleTapListener()
3. GestureDetector使用方法
第一步: 实现OnGestureListener
接口中的方法(可以使用匿名内部类或实现了接口的类实例)
内部类形式
class MyGestureListener implements GestureDetector.OnGestureListener {@Overridepublic boolean onDown(MotionEvent e) {return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}
}
匿名内部类形式
mGestureDetector = new GestureDetector(mContext, new GestureDetector.OnGestureListener() {@Overridepublic boolean onDown(MotionEvent e) {return false;}@Overridepublic void onShowPress(MotionEvent e) {}@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}@Overridepublic void onLongPress(MotionEvent e) {}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}});
第二步: 创建GestureDetector类的实例,构造函数如下:
public GestureDetector(OnGestureListener listener, Handler handler) {this(null, listener, handler);
}public GestureDetector(OnGestureListener listener) {this(null, listener, null);
}public GestureDetector(Context context, OnGestureListener listener) {this(context, listener, null);
}public GestureDetector(Context context, OnGestureListener listener, Handler handler) {
}public GestureDetector(Context context, OnGestureListener listener, Handler handler,boolean unused) {this(context, listener, handler);
}
前两个已经废弃了。
mGestureDetector = new GestureDetector(mContext,new MyGestureListener());
第三步: 实现View.OnTouchListener
接口,重写onTouch()
方法
第四步: 在onTouch()
方法中拦截事件处理,将控制权交给GestureDector
。
@Override
public boolean onTouch(View v, MotionEvent event) {return mGestureDetector.onTouchEvent(event);
}
第五步: 调用控件的View.setOnTouchListener()
将接口的具体实现的引用传递进去或者如果是监听双击的话调用GestureDetector .setOnDoubleTapListener()
super.setOnTouchListener(this);
mGestureDetector.setOnDoubleTapListener(new MyGestureListener());
完整代码
package com.example.gesturetest;import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;/** Created by pingkun.huang on 2016/4/16.*/
public class MyView extends View implements View.OnTouchListener{private Context mContext;private GestureDetector mGestureDetector;private static final String TAG = "MyView";public MyView(Context context) {super(context);initData(context);}public MyView(Context context, AttributeSet attrs) {super(context, attrs);initData(context);}public MyView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initData(context);}private void initData(Context context) {this.mContext = context;super.setOnTouchListener(this);super.setClickable(true);super.setLongClickable(true);super.setFocusable(true);mGestureDetector = new GestureDetector(mContext,new MyGestureListener());mGestureDetector.setOnDoubleTapListener(new MyGestureListener());}/** 当该view上的事件被分发到view上时触发该方法的回调* 如果这个方法返回false时,该事件就会被传递给Activity中的onTouchEvent方法来处理* 如果该方法返回true时,表示该事件已经被onTouch函数处理玩,不会上传到activity中处理* 该方法属于View.OnTouchListening接口*/@Overridepublic boolean onTouch(View v, MotionEvent event) {return mGestureDetector.onTouchEvent(event);}/** 手势监听类*/class MyGestureListener extends GestureDetector.SimpleOnGestureListener {public MyGestureListener() {super();}@Overridepublic boolean onDoubleTap(MotionEvent e) {Log.e(TAG, "onDoubleTap");return true;}@Overridepublic boolean onDoubleTapEvent(MotionEvent e) {Log.e(TAG, "onDoubleTapEvent");return true;}@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {Log.e(TAG, "onSingleTapConfirmed");return true;}@Overridepublic boolean onContextClick(MotionEvent e) {Log.e(TAG, "onContextClick");return true;}@Overridepublic boolean onDown(MotionEvent e) {Log.e(TAG, "onDown");return true;}@Overridepublic void onShowPress(MotionEvent e) {Log.e(TAG, "onShowPress");}@Overridepublic boolean onSingleTapUp(MotionEvent e) {Log.e(TAG, "onSingleTapUp");return true;}@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {Log.e(TAG, "onScroll");return true;}@Overridepublic void onLongPress(MotionEvent e) {Log.e(TAG, "onLongPress");}@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {Log.e(TAG, "onFling");return true;}}
}
MyView
是一个自定义控件继承了View
实现了View.OnTouchListener
。监听的方法用的是继承SimpleOnGestureListener
类,重写了所有方法,仅打印log日志,具体功能自己根据业务重写。
4. GesturetDetector.OnGestureListener 接口
class MyGestureListener implements GestureDetector.OnGestureListener {/** 每按一下屏幕立即触发*/@Overridepublic boolean onDown(MotionEvent e) {return false;}/** 用户按下屏幕并且没有移动或松开。主要是提供给用户一个可视化的反馈,告诉用户他们的按下操作已经* 被捕捉到了。如果按下的速度很快只会调用onDown(),按下的速度稍慢一点会先调用onDown()再调用onShowPress().*/@Overridepublic void onShowPress(MotionEvent e) {}/** 一次单纯的轻击抬手动作时触发*/@Overridepublic boolean onSingleTapUp(MotionEvent e) {return false;}/** 屏幕拖动事件,如果按下的时间过长,调用了onLongPress,再拖动屏幕不会触发onScroll。拖动屏幕会多次触发* @param e1 开始拖动的第一次按下down操作,也就是第一个ACTION_DOWN* @parem e2 触发当前onScroll方法的ACTION_MOVE* @param distanceX 当前的x坐标与最后一次触发scroll方法的x坐标的差值。* @param diastancY 当前的y坐标与最后一次触发scroll方法的y坐标的差值。*/@Overridepublic boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {return false;}/** 长按。在down操作之后,过一个特定的时间触发*/@Overridepublic void onLongPress(MotionEvent e) {}/** 按下屏幕,在屏幕上快速滑动后松开,由一个down,多个move,一个up触发* @param e1 开始快速滑动的第一次按下down操作,也就是第一个ACTION_DOWN* @parem e2 触发当前onFling方法的move操作,也就是最后一个ACTION_MOVE* @param velocityX:X轴上的移动速度,像素/秒* @parram velocityY:Y轴上的移动速度,像素/秒*/@Overridepublic boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {return false;}
}
快按屏幕:onDown
慢按屏幕:onDown
–>onShowPress
按下屏幕等待一段时间onDown
–>onShowPress
–>onLongPress
拖动屏幕:onDown
–>onShowPress
–>onScroll
(多个)–>onFling
快速滑动:onDown
–>onScroll
(多个)–>onFling
5. GesttureDetector.OnDoubleTapListener 接口
class MyDoubleTapListener implements GestureDetector.OnDoubleTapListener {/** 单击事件。用来判定该次点击是单纯的SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,* 如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,* 然后触发SingleTapConfirmed事件。触发顺序是:OnDown->OnsingleTapUp->OnsingleTapConfirmed* 关于onSingleTapConfirmed和onSingleTapUp的一点区别:二者的区别是:onSingleTapUp,只要手抬起就会执行,* 而对于onSingleTapConfirmed来说,如果双击的话,则onSingleTapConfirmed不会执行。*/@Overridepublic boolean onSingleTapConfirmed(MotionEvent e) {return false;}/* * 双击事件*/@Overridepublic boolean onDoubleTap(MotionEvent e) {return false;}/** 双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件*/@Overridepublic boolean onDoubleTapEvent(MotionEvent e) {return false;}
}
双击:onDown
–>onSingleTapUp
–>onDoubleTap
–>onDoubleTapEvent
–>onDown
–>onDoubleTapEvent
6. GesttureDetector.SimpleOnGestureListener 类
结合了OnGestureListener
,OnDoubleTapListener
和OnContextClickListener
中的所有方法,可以有选择的去重写其中的方法,参考前两节。
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!