GestureDetector
为什么要使用 GestureDetector 类?因为使用它可以很轻松的监听单击,双击,按下等许多手势事件的发生,并且做出相应的处理。GestureDetector 类使用了 MotionEvent 提供的方法来监听事件发生,并且调用 GestureDetector 提供的回调方法来给与一个反馈。想要使用 GestureDetector 类需要完成以下工作
GestureDetector 的构造函数
为指定视图创建一个 GestureDetector 的实例
在 Activity 中调用 onTouchEvent(MotionEvent) 方法,借用此方法,调用 GestureDetector 提供给我们的 onTouchEvent(MotionEvent) 方法。
下面来执行第一步,也即创建一个 GestureDetector 实例,而创建该实例有三个方法,就是说它有三个构造函数
1.GestureDetector(Context context,GestureDetector.onGestureListener listener)
2.GestureDetector((Context context, GestureDetector.OnGestureListener listener, Handler handler) //该方法提供了一个Handler 对象,因此该构造方法实例化的对象可以处理一些独立于主线程且延迟的操作
3.GestureDetector (Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused)
介绍完了构造函数,下面就来详细介绍一下 GestureDetector 相关的一些接口和具体类
GestureDetector 相关的接口和具体类
1.interface GestureDetector.OnContextClickListener
这是一个简单的接口,其中只包含一个方法,也即 onContextClick(MotionEvent e) ,用于监听一个Context被点击的事件,值得注意的是,使用这个接口时,我们应该调用 onGenericMotionEvent(MotionEvent) 方法去监听时间的发生。
2.interface GestureDetector.OnDoubleTapListener, 听名字就知道,这个接口主要用于监听双击事件。这个接口中有三个方法。
public abstract boolean onDoubleTap (MotionEvent e) //监听双击事件
public abstract boolean onDoubleTapEvent (MotionEvent e) //这个方法比上述方法强一些,不仅可以监听双击事件,连续移动两次或者抬起两次,都可以触发该方法。
public abstract boolean onSingleTapConfirmed (MotionEvent e) //这个方法可以监听单击事件,这里的单击事件是指确定只点击了一次没有在点击第二次,和GestureDetector.OnGestureListener 中的 onSingleTapUp(MotionEvent e) 方法是不同的。
3.interface GestureDetector.OnGestureListener 这个接口就是实例化 GestureDetector 所必须提供的 Listener, 这个方法中提供了六个方法。
public abstract boolean onDown (MotionEvent e) //监听按下事件
public abstract boolean onFling (MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) // 监听快速滑动事件,参数 e1 是刚按下时的那个 Motionevent,e2是滑动时的那个 MotionEvent,velocityX 是在 x 轴上的滑动速率,velocityY 是在 y 轴上的滑动速率。
public abstract void onLongPress (MotionEvent e) //监听长点击事件
public abstract boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) // 监听滚动事件,参数和onFling 类似
public abstract void onShowPress (MotionEvent e) // 如果用户一直按着界面不抬起,就会触发该方法,该方法和 onLongPress() 方法不同,因为 onLongPress() 只有在用户长点击之后抬起才会触发,而该方法不抬起照样会触发。
public abstract boolean onSingleTapUp (MotionEvent e) // 单击并抬起会触发该方法
4.GestureDetector.SimpleOnGestureListener
这是一个具体类,继承自GestureDetector.OnGestureListener GestureDetector.OnDoubleTapListener GestureDetector.OnContextClickListener 这三个接口,并且提供了默认实现,这也就是说我们可以写一个子类继承它,并且复写我们想要的方法,有点类似 Java GUI 中的 Adapter 类 。
使用 GestureDetector.OnGestureListener
public class MyOnGestureListener implements GestureDetector.OnGestureListener{
private Context mContext;
public MyOnGestureListener(Context context){
mContext = context;
}
@Override
public boolean onDown(MotionEvent motionEvent) {
Toast.makeText(mContext, "onDown ", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
Toast.makeText(mContext, "onShowPress",Toast.LENGTH_SHORT).show();
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
Toast.makeText(mContext, "onSingleTapUp", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Toast.makeText(mContext, "onScroll", Toast.LENGTH_SHORT).show();
return true;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
Toast.makeText(mContext, "onLongPress", Toast.LENGTH_SHORT).show();
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Toast.makeText(mContext, "onFling", Toast.LENGTH_SHORT).show();
return true;
}
}
public class MainActivity extends AppCompatActivity {
private GestureDetector mDetector;
private MyOnGestureListener mGestureListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGestureListener = new MyOnGestureListener(this);
mDetector = new GestureDetector(this, mGestureListener);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
}
请注意,在以上各个函数的实现中,凡是返回值为 boolean 的,都要返回 true 这样方法才能在具体事件发生时被调用,否则该方法不会被事件触发。 在以上方法的实现中,只是简单的调用了 toast 方法,其实在这里我们可以完成很多功能。
可见使用该方法有一个缺陷,就是我们需要为所有方法提供一个实现,包括我们不想要的方法,这是非常耽误时间的,所以才有了 GestureDetector.SimpleOnGestureListener
使用 GestureDetector.SimpleOnGestureListener
public class MySimpleGesture extends GestureDetector.SimpleOnGestureListener{
private Context mContext;
public MySimpleGesture(Context context){
mContext = context;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
Toast.makeText(mContext, "Double Tap", Toast.LENGTH_SHORT).show();
return true;
}
}
public class MainActivity extends AppCompatActivity {
private GestureDetector mDetector;
private MySimpleGesture mSimpleGesture;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSimpleGesture = new MySimpleGesture(this);
mDetector = new GestureDetector(this, mSimpleGesture);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}
}
可以在 MySimpleGesture 类中实现自己需要的方法。