Android 手势基础 GestureDetector

版权声明:本文为博主原创文章,欢迎转载但需注明出处谢谢! https://blog.csdn.net/dongxianfei/article/details/90177078

当用户触摸屏幕的时候,会产生许多手势,例如down,up,scroll,filing等等,我们知道View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,但是这个方法太过简单,如果需要处理一些复杂的手势,Android SDK给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势,主要是通过他的onTouchEvent(event)方法完成了不同手势的识别。虽然他能识别手势,但是不同的手势要怎么处理,应该是提供给程序员实现的,因此这个类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener,SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,这个类实现了上述两个接口。

通过GestureDetector的构造方法可以将SimpleOnGestureListener对象传递进去,这样GestureDetector能处理不同的手势了。

下面是个简单的例子,首先重写GestureDetector类:

import android.view.GestureDetector.SimpleOnGestureListener;  
import android.view.MotionEvent;  
  
/** 
 * 
 *点击一下非常快的(不滑动)Touchup:  
 *onDown->onSingleTapUp->onSingleTapConfirmed  
 *点击一下稍微慢点的(不滑动)Touchup:  
 *onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed 
 **/  
public class MyGestureDetector extends SimpleOnGestureListener {  
      
    /** 
     * 双击的第二下Touch down时触发 
     */  
    @Override  
    public boolean onDoubleTap(MotionEvent e) {  
        System.out.println("*********onDoubleTap*******");  
        return super.onDoubleTap(e);  
    }  
      
    /** 
     * 双击的第二下Touch down和up都会触发,可用e.getAction()区分。  
     */  
    @Override  
    public boolean onDoubleTapEvent(MotionEvent e) {  
        System.out.println("*********onDoubleTapEvent*******");  
        return super.onDoubleTapEvent(e);  
    }  
      
    /** 
     * Touch down时触发  
     */  
    @Override  
    public boolean onDown(MotionEvent e) {  
        System.out.println("*********onDown*******");  
        return super.onDown(e);  
    }  
      
    /** 
     * Touch了滑动一点距离后,up时触发。  
     */  
    @Override  
    public boolean onFling(MotionEvent e1, MotionEvent e2, float x,  
            float y) {  
        System.out.println("*********onFling*******" + x + "******" + y);  
        return super.onFling(e1, e2, x, y);  
    }  
      
    /** 
     * Touch了不移动一直Touch down时触发  
     */  
    @Override  
    public void onLongPress(MotionEvent e) {  
        System.out.println("*********onLongPress*******");  
        super.onLongPress(e);  
    }  
  
    /**Touch了滑动时触发。  
     *输出x,y值 
     * 向上划动y为正,向左划时x为正 e1为划动时的Event,e2,为划动后的Event 
     */  
    @Override  
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float x,  
            float y) {  
        System.out.println("*********onScroll*******" + x + "*******" + y);  
        return super.onScroll(e1, e2, x, y);  
    }  
  
    /** 
     * Touch了还没有滑动时触发  
     * onDown只要Touch down一定立刻触发。  
     * 而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。  
     * 所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。 
     */  
    @Override  
    public void onShowPress(MotionEvent e) {  
        System.out.println("*********onShowPress*******");  
        super.onShowPress(e);  
    }  
  
    /** 
     * 和onSingleTapup不一样,当监听器确定没有第二次按下事件时,才调用此方法,也就是onSingleTapUp不能确定是单击还是双击,而此方法响应可以确定一定是单击 
     */  
    @Override  
    public boolean onSingleTapConfirmed(MotionEvent e) {  
        System.out.println("*********onSingleTapConfirmed*******");  
        return super.onSingleTapConfirmed(e);  
    }  
  
    /** 
     * 只要按下就会调用此方法,当双击时,第一次按下时会调用此方法,而第二次不会调用 
     */  
    @Override  
    public boolean onSingleTapUp(MotionEvent e) {  
        System.out.println("*********onSingleTapUp*******");  
        return super.onSingleTapUp(e);  
    }  
  
}  
public class AaActivity extends Activity {  
    MyGestureDetector myGestureDetector = null;  
    GestureDetector gestureDetector = null;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        gestureDetector = new GestureDetector(this, new MyGestureDetector());  
         
    }  
    @Override  
    public boolean onTouchEvent(MotionEvent event) {  
        return gestureDetector.onTouchEvent(event);  
    }  
}  
boolean  onSingleTapConfirmed(MotionEvent e)
boolean  onSingleTapUp(MotionEvent e)
上面这两个函数都是在touch down后又没有滑动(onScroll),又没有长按(onLongPress),然后Touchup时触发。

void  onLongPress(MotionEvent e)
Touch了不移动一直Touch down时触发

boolean  onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
Touch了滑动时触发。

boolean  onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
Touch了滑动一点距离后,up时触发。

void  onShowPress(MotionEvent e)
Touch了还没有滑动时触发
(与onDown,onLongPress比较,onDown只要Touch down一定立刻触发。
而Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
所以Touchdown后一直不滑动,onDown->onShowPress->onLongPress这个顺序触发。)

boolean  onDown(MotionEvent e)
Touch down时触发

boolean  onDoubleTap(MotionEvent e)
双击的第二下Touch down时触发

boolean  onDoubleTapEvent(MotionEvent e)
双击的第二下Touch down和up都会触发,可用e.getAction()区分。


1. 点击屏幕上的某项的执行流程 有两种情况,一种是时间很短,一种时间稍长
时间很短:onDown——–》onSingleTapUp——–》onSingleTapConfirmed
时间稍长:onDown——–》onShowPress——》onSingleTapUp——–》onSingleTapConfirmed
2. 长按事件
onDown——–》onShowPress——》onLongPress
3.抛:手指触动屏幕后,稍微滑动后立即松开
onDown—–》onScroll—-》onScroll—-》onScroll—-》………—–>onFling
4.拖动
onDown——》onScroll—-》onScroll——》onFiling
注意:有的时候会触发onFiling,但是有的时候不会触发,个人理解是人的动作不标准所致。

ScaleGestureDetector这个类是专门用来检测两个手指在屏幕上做缩放的手势用的,最简单的应用就是用来缩放图片或者缩放网页。
这个类通常与GestureDetector一起存在,用来处理复杂的手势操作。
通常是单手指和双手指操作,所以通常存在一个判断手指个数然后分发事件的处理方法。

//SimpleOnGestureListener implements OnGestureListener, OnDoubleTapListener
	class ZoomGesture extends GestureDetector.SimpleOnGestureListener {//单手指操作
		
		@Override //双击
		public boolean onDoubleTap(MotionEvent e) {
			System.out.println("--onDoubleTap---");
			return true;
		}
 
		@Override
		public boolean onDoubleTapEvent(MotionEvent e) {
			System.out.println("--onDoubleTapEvent---");
			return super.onDoubleTapEvent(e);
		}
	}
	
	//SimpleOnScaleGestureListener implements OnScaleGestureListener
	class 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();  //与上次事件相比,得到的比例因子
			return true;
		}	
	}
private GestureDetector gestureDetector; //手势探测器
private ScaleGestureDetector scaleGestureDetector;//比率手势探测器
gestureDetector = new GestureDetector(context, new ZoomGesture());
scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGesture());
 
public boolean onTouchEvent(MotionEvent event) {
	  //单点
	gestureDetector.onTouchEvent(event);
	  //双点 
	scaleGestureDetector.onTouchEvent(event);
	return true;

猜你喜欢

转载自blog.csdn.net/dongxianfei/article/details/90177078