相信大家都用过GestureDetector手势识别器,一般常用场景都是在自定义控件当中对滑动手势操作。最近也用到了手势识别器就看了源码翻译一下,再此做个记录,希望能帮助到大家。首先我们要知道GestureDetector继承的是Object类,也是在android.view包下面,那我们就继续看一下这个类的一些方法和接口。
/**
* Detects various gestures and events using the supplied {@link MotionEvent}s.
* The {@link OnGestureListener} callback will notify users when a particular
* motion event has occurred. This class should only be used with {@link MotionEvent}s
* reported via touch (don't use for trackball events).
*
* To use this class:
* <ul>
* <li>Create an instance of the {@code GestureDetector} for your {@link View}
* <li>In the {@link View#onTouchEvent(MotionEvent)} method ensure you call
* {@link #onTouchEvent(MotionEvent)}. The methods defined in your callback
* will be executed when the events occur.
* <li>If listening for {@link OnContextClickListener#onContextClick(MotionEvent)}
* you must call {@link #onGenericMotionEvent(MotionEvent)}
* in {@link View#onGenericMotionEvent(MotionEvent)}.
* </ul>
*/
这个类的解释:
通过系统提供的MotionEvent来监测各种手势和(触摸)事件。当一个指定的手势事件发生时,GestureDetector.OnGestureListener回调函数将通告用户。这个类仅仅处理由触摸引发的MotionEvent(不能处理由轨迹球引发的事件)。要使用这个类需执行以下操作:
1.为你的View建立一个GestureDetector实例。
2.在View的onTouchEvent(MotionEvent)方法里确保调用(GestureDetector的)onTouchEvent(MotionEvent)方法。当相关事件发生时,定义在回调函数里的方法将被执行。
几个接口里的方法:
public interface OnGestureListener{
/**
* Notified when a tap occurs with the down {@link MotionEvent}
* that triggered it. This will be triggered immediately for
* every down event. All other events should be preceded by this.
*
* @param e The down motion event.向下运动事件。
*/当发生轻击时发生向下{@link MotionEvent}触发它。这将立即触发每个下降事件。 所有其他事件应该在这之前。
boolean onDown(MotionEvent e);
/**
* The user has performed a down {@link MotionEvent} and not performed
* a move or up yet. This event is commonly used to provide visual
* feedback to the user to let them know that their action has been
* recognized i.e. highlight an element.
*
* @param e The down motion event 向下运动事件。
用户已执行了{@link MotionEvent},但未执行移动或向上。 此事件通常用于提供可视化反馈给用户,让他们知道他们的行动已经识别,即突出显示一个元素。
void onShowPress(MotionEvent e);
/**
* Notified when a tap occurs with the up {@link MotionEvent}
* that triggered it.
*
* @param e The up motion event that completed the first tap
* @return true if the event is consumed, else false
当发生轻击时通知{@link MotionEvent}触发它。 @param e完成第一次敲击的向上运动事件 @如果事件被消耗则返回true,否则为false
boolean onSingleTapUp(MotionEvent e);
/**
* Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
* current move {@link MotionEvent}. The distance in x and y is also supplied for
* convenience.
*
* @param e1 The first down motion event that started the scrolling.
* @param e2 The move motion event that triggered the current onScroll.
* @param distanceX The distance along the X axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1}
* and {@code e2}.
* @param distanceY The distance along the Y axis that has been scrolled since the last
* call to onScroll. This is NOT the distance between {@code e1}
* and {@code e2}.
* @return true if the event is consumed, else false
*/在初始向下滚动时发生滚动{@link MotionEvent}和
*当前移动{@link MotionEvent}。 还提供x和y中的距离
* 方便。
*:
* @param e1开始滚动的第一个向下运动事件。
* @param e2触发当前onScroll的移动运动事件。
* @param distanceX自上次以来滚动的X轴上的距离
*调用onScroll。 这不是{@code e1}
*和{@code e2}。
* @param distanceY自上次以来滚动的Y轴上的距离
*调用onScroll。 这不是{@code e1}
*和{@code e2}。
* @如果事件被消耗则返回true,否则为false
boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);
/**
* Notified when a long press occurs with the initial on down {@link MotionEvent}
* that trigged it.
*
* @param e The initial on down motion event that started the longpress.
*/当长按初始化时,通知{@link MotionEvent}
*触发它。
* @param e启动长按的初始向下运动事件
void onLongPress(MotionEvent e);
/**
* Notified of a fling event when it occurs with the initial on down {@link MotionEvent}
* and the matching up {@link MotionEvent}. The calculated velocity is supplied along
* the x and y axis in pixels per second.
*
* @param e1 The first down motion event that started the fling.
* @param e2 The move motion event that triggered the current onFling.
* @param velocityX The velocity of this fling measured in pixels per second
* along the x axis.
* @param velocityY The velocity of this fling measured in pixels per second
* along the y axis.
* @return true if the event is consumed, else false
*/通知初始化时发生的fling事件{@link MotionEvent}
*和匹配{@link MotionEvent}。 沿着计算的速度提供
* x和y轴以像素每秒为单位。
*:
* @param e1启动fling的第一个向下运动事件。
* @param e2触发当前onFling的移动运动事件。
* @param velocityX此fling的速度以像素每秒为单位测量
*沿x轴。
* @param velocityY此fling的速度以像素每秒为单位测量
*沿y轴。
* @如果事件被消耗则返回true,否则为false
boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY);
}
/**
* The listener that is used to notify when a double-tap or a confirmed
* single-tap occur.
*/用于在双击或确认时通知的侦听器
*单击发生。
public interface OnDoubleTapListener {
/**
* Notified when a single-tap occurs.
* <p>
* Unlike {@link OnGestureListener#onSingleTapUp(MotionEvent)}, this
* will only be called after the detector is confident that the user's
* first tap is not followed by a second tap leading to a double-tap
* gesture.
*
* @param e The down motion event of the single-tap.
* @return true if the event is consumed, else false
*/发生单击时通知。
*不像{@link OnGestureListener#onSingleTapUp(MotionEvent)},这个
*将只有在检测器确信用户的调用
*第一次敲击之后不是第二次敲击导致双击
*手势。
*:
* @param e单击的向下运动事件。
* @如果事件被消耗则返回true,否则为false
boolean onSingleTapConfirmed(MotionEvent e);
/**
* Notified when a double-tap occurs.
*
* @param e The down motion event of the first tap of the double-tap.
* @return true if the event is consumed, else false
*/发生双击时通知。
* @param e双击的第一次敲击的向下运动事件。
* @如果事件被消耗则返回true,否则为false
boolean onDoubleTap(MotionEvent e);
/**
* Notified when an event within a double-tap gesture occurs, including
* the down, move, and up events.
*
* @param e The motion event that occurred during the double-tap gesture.
* @return true if the event is consumed, else false
*/在双击手势中发生事件时通知,包括
*向下,移动和向上事件。
* @param e双击手势期间发生的运动事件。
* @如果事件被消耗则返回true,否则为false
boolean onDoubleTapEvent(MotionEvent e);
}
/**
* The listener that is used to notify when a context click occurs. When listening for a
* context click ensure that you call {@link #onGenericMotionEvent(MotionEvent)} in
* {@link View#onGenericMotionEvent(MotionEvent)}.
*/他用于在发生上下文点击时通知的侦听器。 当听时
*上下文点击确保你调用{@link #onGenericMotionEvent(MotionEvent)}
* {@link View#onGenericMotionEvent(MotionEvent)}。
public interface OnContextClickListener {
/**
* Notified when a context click occurs.
* @param e The motion event that occurred during the context click.
* @return true if the event is consumed, else false
*/发生上下文单击时通知。
* @param e在上下文单击期间发生的运动事件。
* @如果事件被消耗则返回true,否则为false
boolean onContextClick(MotionEvent e);
}
GestureDetector的接口就只有这三个,包括里面都有一些常用的方法。但是在我们实际开发中,如果我们需要实现这3个接口,我们不必一个一个的实现,因为在android系统中已经定义了一个SimpleOnGestureListener类帮我们实现了这几个接口,继续往下看,最后我会贴出一段代码怎么使用这个类。
/**
* A convenience class to extend when you only want to listen for a subset
* of all the gestures. This implements all methods in the
* {@link OnGestureListener}, {@link OnDoubleTapListener}, and {@link OnContextClickListener}
* but does nothing and return {@code false} for all applicable methods.
*/一个方便的类,当你只想监听一个子集时扩展
*所有的手势。 这实现了所有的方法
* {@link OnGestureListener},{@link OnDoubleTapListener}和{@link OnContextClickListener}
*但什么都不做,并返回{@code false}所有适用的方法。
public static class SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener,
OnContextClickListener {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
return false;
}
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
return false;
}
public void onShowPress(MotionEvent e) {
}
public boolean onDown(MotionEvent e) {
return false;
}
public boolean onDoubleTap(MotionEvent e) {
return false;
}
public boolean onDoubleTapEvent(MotionEvent e) {
return false;
}
public boolean onSingleTapConfirmed(MotionEvent e) {
return false;
}
public boolean onContextClick(MotionEvent e) {
return false;
}
}
一些构造方法:
/**
* Creates a GestureDetector with the supplied listener.
* This variant of the constructor should be used from a non-UI thread
* (as it allows specifying the Handler).
*
* @param listener the listener invoked for all the callbacks, this must
* not be null.
* @param handler the handler to use
*
* @throws NullPointerException if either {@code listener} or
* {@code handler} is null.
*
* @deprecated Use {@link #GestureDetector(android.content.Context,
* android.view.GestureDetector.OnGestureListener, android.os.Handler)} instead.
*/使用提供的侦听器创建GestureDetector。
*此构造函数的变体应该从非UI线程中使用
*(因为它允许指定处理程序)。
* @param listener为所有回调调用的监听器,这必须
*不能为null。
* @param handler使用的处理程序
* @throws NullPointerException如果{@code listener}或
* {@code handler}为null。
@Deprecated
public GestureDetector(OnGestureListener listener, Handler handler) {
this(null, listener, handler);
}
/**
* Creates a GestureDetector with the supplied listener.
* You may only use this constructor from a UI thread (this is the usual situation).
* @see android.os.Handler#Handler()
*
* @param listener the listener invoked for all the callbacks, this must
* not be null.
* @throws NullPointerException if {@code listener} is null.
* @deprecated Use {@link #GestureDetector(android.content.Context,
* android.view.GestureDetector.OnGestureListener)} instead.
*/使用提供的侦听器创建GestureDetector。
*你只能从UI线程使用这个构造函数(这是通常的情况)。
* @see android.os.Handler#Handler()
*:
* @param listener为所有回调调用的监听器,这必须
*不能为null。
@Deprecated
public GestureDetector(OnGestureListener listener) {
this(null, listener, null);
}
/**
* Creates a GestureDetector with the supplied listener.
* You may only use this constructor from a {@link android.os.Looper} thread.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
* @throws NullPointerException if {@code listener} is null.
*/使用提供的侦听器创建GestureDetector。
*你只能从{@link android.os.Looper}线程中使用这个构造函数。
* @see android.os.Handler#Handler()
*:
* @param context应用程序的上下文
* @param listener为所有回调调用的监听器,这必须
*不能为null。
public GestureDetector(Context context, OnGestureListener listener) {
this(context, listener, null);
}
/**
* Creates a GestureDetector with the supplied listener that runs deferred events on the
* thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
* @param handler the handler to use for running deferred listener events.
*
* @throws NullPointerException if {@code listener} is null.
*/使用提供的侦听器创建GestureDetector,在其上运行延迟事件
*线程与提供的{@link android.os.Handler}相关联。
* @see android.os.Handler#Handler()
*:
* @param context应用程序的上下文
* @param listener为所有回调调用的监听器,这必须
*不能为null。
* @param handler用于运行延迟侦听器事件的处理程序。
public GestureDetector(Context context, OnGestureListener listener, Handler handler) {}
/**
* Creates a GestureDetector with the supplied listener that runs deferred events on the
* thread associated with the supplied {@link android.os.Handler}.
* @see android.os.Handler#Handler()
*
* @param context the application's context
* @param listener the listener invoked for all the callbacks, this must
* not be null.
* @param handler the handler to use for running deferred listener events.
* @param unused currently not used.
*
* @throws NullPointerException if {@code listener} is null.
*/使用提供的侦听器创建GestureDetector,在其上运行延迟事件
*线程与提供的{@link android.os.Handler}相关联。
* @see android.os.Handler#Handler()
*:
* @param context应用程序的上下文
* @param listener为所有回调调用的监听器,这必须
*不能为null。
* @param handler用于运行延迟侦听器事件的处理程序。
* @param unused当前未使用。
public GestureDetector(Context context, OnGestureListener listener, Handler handler,
boolean unused) {
this(context, listener, handler);
}
一些公共方法:
/**
* Sets the listener which will be called for double-tap and related
* gestures.
*
* @param onDoubleTapListener the listener invoked for all the callbacks, or
* null to stop listening for double-tap gestures.
*/设置将被双击并相关的监听器
*手势。
*:
* @param onDoubleTapListener为所有回调调用的侦听器,或
* null停止监听双击手势。
public void setOnDoubleTapListener(OnDoubleTapListener onDoubleTapListener) {
mDoubleTapListener = onDoubleTapListener;
}
/**
* Sets the listener which will be called for context clicks.
*
* @param onContextClickListener the listener invoked for all the callbacks, or null to stop
* listening for context clicks.
*/设置将为上下文点击调用的侦听器。
*:
* @param onContextClickListener为所有回调调用的侦听器,或null停止
*监听上下文点击。
public void setContextClickListener(OnContextClickListener onContextClickListener) {
mContextClickListener = onContextClickListener;
}
/**
* Set whether longpress is enabled, if this is enabled when a user
* presses and holds down you get a longpress event and nothing further.
* If it's disabled the user can press and hold down and then later
* moved their finger and you will get scroll events. By default
* longpress is enabled.
*
* @param isLongpressEnabled whether longpress should be enabled.
*/设置是否启用长按,如果在用户启用时启用
*按下并按住,你得到一个longpress事件,没有进一步。
*如果禁用,用户可以按住,然后稍后
*移动他们的手指,你会得到滚动事件。 默认
*启用长按。
* @param isLongpressEnabled是否应启用longpress。
public void setIsLongpressEnabled(boolean isLongpressEnabled) {
mIsLongpressEnabled = isLongpressEnabled;
}
/**
* @return true if longpress is enabled, else false.
*/@return true如果长按启用,否则为false。
public boolean isLongpressEnabled() {
return mIsLongpressEnabled;
}
GestureDetector的一些简介就只有这么几个接口和方法,包括源码中继承Handler和onTouchEvent()方法,特别是onTouchEvent()方法,手势识别器就是依靠这个方法去实现一些操作。我简单的把手势识别器的用法写一下,也就是刚才源码帮我们实现3个接口的那个类。回到这个GestureDetector类的解释,首先要实例化,其次在View的onTouchEvent(MotionEvent)方法里确保调用(GestureDetector的)onTouchEvent(MotionEvent)方法。
private GestureDetector detector; //初始化
private void initView(final Context context) {
//2.实例化手势识别器
detector = new GestureDetector(context,new GestureDetector.SimpleOnGestureListener()
{
@Override
public void onLongPress(MotionEvent e) {
super.onLongPress(e);
Toast.makeText(context,"长按",Toast.LENGTH_SHORT).show();
}
/**
*
* @param e1
* @param e2
* @param distanceX 在X轴滑动了的距离
* @param distanceY 在Y轴滑动了的距离
* @return
*/
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
/**
*x:要在X轴移动的距离
*y:要在Y轴移动的距离
*/
scrollBy((int)distanceX,0);
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(context,"双击",Toast.LENGTH_SHORT).show();
return super.onDoubleTap(e);
}
}); //这里就是new的SimpleOnGestureListener类,还有很多方法这里只贴出了这几个。
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
//3.把事件传递给手势识别器
detector.onTouchEvent(event); //一定要传递进来,不然就没作用
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
System.out.println("onTouchEvent==ACTION_DOWN");
break;
case MotionEvent.ACTION_MOVE:
System.out.println("onTouchEvent==ACTION_MOVE");
break;
case MotionEvent.ACTION_UP:
System.out.println("onTouchEvent==ACTION_UP");
break;
}
return true;
}
这就是GestureDetector手势识别器的简单用法,其它复杂化的就不写了。下面贴几个手势识别器的用法的网站,供大家参考!2016年就这样完了,明年继续奋斗。在技术的学习上就是要多花时间,认真认真再认真。我感觉csdn的编辑器不行啊,不知道是不是我没找到方法。
http://www.cnblogs.com/transmuse/archive/2010/12/02/1894833.html
http://blog.csdn.net/xyz_lmn/article/details/16826669