当我们处理一些简单的点击,滑动事件的时候可以直接给View设置一个已经实现好的监听器。但是当我们进行一些复杂手势的识别以及处理的时候,系统已经实现好的监听器就不够用了,当然我们可以通过onTouch()中的MotionEvent的getAction获取当前用户手势所触发的事件, 如:ACTION_DOWN,ACTION_UP,ACTION_MOVE,也可以获取到当前手指点击的坐标,通过getX(),getY()进行获取。
imageView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
int Action = motionEvent.getAction();
switch (Action){
case MotionEvent.ACTION_DOWN:
Log.i("wk","手指按下");
break;
case MotionEvent.ACTION_MOVE:
Log.i("wk","手指移动"+"x坐标:"+ motionEvent.getX());
break;
case MotionEvent.ACTION_UP:
Log.i("wk","手指抬起");
break;
}
return false;
}
});
假设当我们需要识别用户的双击事件时,我们还得需要可以在onTouch()中进行书写相应的代码进行判断,因此遇到这种情况我们便可以使用谷歌给我们提供的GestureDetector类来检测用户的手势操作。
通过官方文档的描述可以知道GestureDetector类对外提供了两个接口和一个静态类
接口:OnGestureListener,OnDoubleTapListener 静态类:SimpleOnGestureListener
下面梳理一遍 实现OnGestureListener接口进行GestureDetector 手势识别的使用步骤:
1.首先创建OnGestureListener的监听函数:
创建一个类实现GestureDetector.OnGestureListener接口,实现方法
class MyGestureListener implements GestureDetector.OnGestureListener {
}
2.创建 GestureDetector对象实例,传入上一步实现了GestureDetector.OnGestureListener接口类的实例:
GestureDetector mGestureDetector = new GestureDetector(this, new MyGestureListener());
3.设置需要进行手势监听的View的OnTouchListener的监听,重写onTouch()方法。
public class GestureDetectorActivity extends AppCompatActivity implements View.OnTouchListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gesture_detector);
//设置View的触摸监听,实现接口的方式实现
imageView.setOnTouchListener(this);
}
imageView.setOnTouchListener(this);
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mGestureDetector.onTouchEvent(motionEvent);
}
}
4.在 onTouch()中,让GestureDetector接收处理触摸事件:
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mGestureDetector.onTouchEvent(motionEvent);
}
当将onTouch( )的触摸事件交给GestureDetector处理的时候,此时的GestureDetector类就可以进行手势监听了。
下面看一下 GestureDetector.OnGestureListener接口中需要实现的方法:
class MyGestureListener implements GestureDetector.OnGestureListener{
//按下屏幕就会触发
@Override
public boolean onDown(MotionEvent motionEvent) {
Log.i("wk", "==>onDown()");
return false;
}
//如果是按下的时间超过瞬间,而且在按下的时候没有松开或者是拖动时触发
@Override
public void onShowPress(MotionEvent motionEvent) {
Log.i("wk", "==>onShowPress()");
}
//轻击一下屏幕,立刻抬起来,才会有这个触发
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
Log.i("wk", "==>onSingleTapUp()");
return false;
}
//在屏幕上拖动事件。无论是用手拖动view,或者是以抛的动作滚动,都会多次触发,这个方法
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float distanceX, float distanceY) {
Log.i("wk", "==>onScroll()");
return false;
}
//长按触摸屏,超过一定时长,就会触发这个事件
@Override
public void onLongPress(MotionEvent motionEvent) {
Log.i("wk", "==>onLongPress()");
}
//滑屏,用户按下触摸屏、快速移动后松开
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("wk", "==>onFling()");
return false;
}
}
这时开始郁闷了,为什么没有双击事件的监听呢?看前面我们知道GestureDetector类还提供了一个OnDoubleTapListener的接口,再同时实现这个接口,就可以实现双击的手势监听了。
//双击事件相关的监听
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
Log.i("wk", "==>onSingleTapConfirmed()");
return false;
}
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
Log.i("wk", "==>onDoubleTap()");
return false;
}
@Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
Log.i("wk", "==>onDoubleTapEvent()");
return false;
}
也可以通过 GestureDetector.setOnDoubleTapListener()使用内部类的方式实现双击的监听:
mGestureDetector = new GestureDetector(this, new MyGestureListener());
mGestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
// 用来判定该次点击是SingleTap而不是DoubleTap,如果连续点击两次就是DoubleTap手势,如果只点击一次,系统等待一段时间后没有收到第二次点击则判定该次点击为SingleTap而不是DoubleTap,然后触发SingleTapConfirmed事件。
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
return false;
}
//双击事件
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
return false;
}
//双击间隔中发生的动作。指触发onDoubleTap以后,在双击之间发生的其它动作,包含down、up和move事件
@Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
return false;
}
});
GestureDetector.SimpleOnGestureListener 静态类的使用:
所有步骤与使用OnGestureListener实现接口的方式进行手势监听步骤一致,不同的是此处需要继承GestureDetector.SimpleOnGestureListener类实现手势的监听方法。相比实现接口的方式,使用继承的方式可以根据我们的需求实现用得到的方法,而不需要像实现接口那样将所有的方法全都重写。
下面用一个小例子来练习一下GestureDetector手势识别的使用:
(在ImageView上左右滑动实现图片的切换)
代码:
//滑屏,用户按下触摸屏、快速移动后松开
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("wk", "==>onFling()");
//手指按下的位置
float downX = motionEvent.getX();
float downY = motionEvent.getY();
//手指抬起的位置
float upX = motionEvent1.getX();
float upY = motionEvent1.getY();
float xDistance = downX - upX;
float yDistance = downY - upY;
Log.i("wk","downX:"+downX+"upX:"+upX);
//判断当前手指滑动的方向,判断如果滑动的像素大于200并且是偏向水平方向时执行
if(xDistance>0 && Math.abs(xDistance)>200 && Math.abs(xDistance)-Math.abs(yDistance)>0 ){
Toast.makeText(GestureDetectorActivity.this,"右滑",Toast.LENGTH_SHORT).show();
if(mIndex == Images.length-1){
Toast.makeText(GestureDetectorActivity.this,"已经滑动到最后一张图片了",Toast.LENGTH_SHORT).show();
}else {
imageView.setImageResource(Images[mIndex]);
mIndex++;
}
}else if(xDistance<0 && Math.abs(xDistance)>200 && Math.abs(xDistance)-Math.abs(yDistance)>0) {
Toast.makeText(GestureDetectorActivity.this,"左滑",Toast.LENGTH_SHORT).show();
if(mIndex == 0){
Toast.makeText(GestureDetectorActivity.this,"已经滑动到第一张张图片了",Toast.LENGTH_SHORT).show();
}else {
imageView.setImageResource(Images[mIndex]);
mIndex--;
}
}
return false;
}
上述例子比较简单,只需要根据手指按下的位置,以及抬起的位置判断滑动的方向即可。
眼睛酸涩………… 撒花~(≧▽≦)/~啦啦啦