当用户触摸屏幕的时候,会产生很多手势,例如down,up,scroll,filling等。

View类有一个内部接口——View.OnTouchListener,通过重写这个内部类的onTouch(View v,MotionEvent event)方法,可以处理一些简单的touch事件。但是如果需要处理一些复杂的手势,用这个接口会很麻烦。

Android sdk提供给我们了一个手势(Gesture)识别(Detector)类,通过这个类我们可以识别很多手势,主要是通过它的onTouchEvent(event)方法完成了不同手势的识别。

这个类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener。SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的、经过简化的响应不同手势的类,这个类实现了上述两个类的接口(但是所有的方法都是空的),该类是static class,也就是说它实际上是一个外部类。我们可以在外部继承这个类,重写里面的手势处理方法。

启动手势识别类的方法:

           GestureDetector mGestureDetector = new GestureDetector(new FlingGestureDector());

其中FlingGestureDetector()为重写的手势识别类

 

手势识别类FlingGestureDetector()的定义:

private class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener {

   // 用户轻触触摸屏,由1个MotionEvent ACTION_DOWN触发    

  //Touch down时触发,不论是touch (包括long) ,scroll
    @Override  
    public boolean onDown(MotionEvent e) {  
        // TODO Auto-generated method stub   
        System.out.println("onDown");  
        return false;  
    } 

   /* 
     * 用户轻触触摸屏,尚未松开或拖动,由一个1个MotionEvent ACTION_DOWN触发 
     * 注意和onDown()的区别,强调的是没有松开或者拖动的状态 (单击没有松开或者移动时候就触发此事件,再触发onLongPress事件) 
     */   

//Touch了还没有滑动时触发
     //(与onDown,onLongPress比较
     //onDown只要Touch down一定立刻触发。

    @Override  
    public void onShowPress(MotionEvent e) {  
        // TODO Auto-generated method stub   
        System.out.println("onShowPress");  
    }   
   
    // 用户(轻触触摸屏后)松开,由一个1个MotionEvent ACTION_UP触发    
    @Override  
    public boolean onSingleTapUp(MotionEvent e) {  
        // TODO Auto-generated method stub   
        System.out.println("onSingleTopUp");  
        return false;  
    }   
   
    // 用户按下触摸屏,并拖动,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE触发    
    @Override  
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
            float distanceY) {  
        System.out.println("onScroll");  
        // TODO Auto-generated method stub   
        return false;  
    }   
   
    // 用户长按触摸屏,由多个MotionEvent ACTION_DOWN触发 

//Touch了不移动一直Touch down时触发
     //Touchdown后过一会没有滑动先触发onShowPress再是onLongPress。
   
    @Override  
    public void onLongPress(MotionEvent e) {  
        // TODO Auto-generated method stub   
        System.out.println("onLongPress");  
    }   
   
    /* 
     * 用户按下触摸屏、快速移动后松开,由1个MotionEvent ACTION_DOWN, 多个ACTION_MOVE, 
     * 1个ACTION_UP触发(non-Javadoc) 
     * Fling事件的处理代码:除了第一个触发Fling的ACTION_DOWN和最后一个ACTION_MOVE中包含的坐标等信息外 
     * ,我们还可以根据用户在X轴或者Y轴上的移动速度作为条件 
     * 比如下面的代码中我们就在用户移动超过100个像素,且X轴上每秒的移动速度大于200像素时才进行处理。 
     *  
     * @see Android.view.GestureDetector.OnGestureListener#onFling(android.view. 
     * MotionEvent, Android.view.MotionEvent, float, float) 
     * 这个例子中,tv.setLongClickable( true )是必须的,因为 
     * 只有这样,view才能够处理不同于Tap(轻触)的hold(即ACTION_MOVE,或者多个ACTION_DOWN) 
     * ,我们同样可以通过layout定义中的Android:longClickable来做到这一点 
     */   
    @Override  
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,  
            float velocityY) {  
        // TODO Auto-generated method stub   
        System.out.println("onFling");   
        // 参数解释:   
        // e1:第1个ACTION_DOWN MotionEvent   
        // e2:最后一个ACTION_MOVE MotionEvent   
        // velocityX:X轴上的移动速度,像素/秒   
        // velocityY:Y轴上的移动速度,像素/秒   
  
        // 触发条件 :   
        // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒    
        final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;  
        if (e1.getX() - e2.getX() > FLING_MIN_DISTANCE  
                && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
            // Fling left   
            Log.i("MyGesture", "Fling left");  
            Toast.makeText(context, "Fling Left", Toast.LENGTH_SHORT).show();  
        } else if (e2.getX() - e1.getX() > FLING_MIN_DISTANCE  
                && Math.abs(velocityX) > FLING_MIN_VELOCITY) {  
            // Fling right   
            Log.i("MyGesture", "Fling right");  
            Toast.makeText(context, "Fling Right", Toast.LENGTH_SHORT).show();  
        }  
        return true;  
    }   
   
 

关于返回值的认知:

如果GestureDetector.SimpleOnGestureListener消耗掉了这个事件,则返回true,否则返回false

当然最后不要忘记在你的Activity中override onTouch方法来获取手势action:


Java代码 
@Override  
public boolean onTouchEvent(MotionEvent event) {   
    if (gestureDetector.onTouchEvent(event))   
        return true;   
    else  
        return false;   
}

 

1. 点击屏幕上的某项的执行流程  有两种情况,一种是时间很短,一种时间稍长

时间很短:onDown--------》onSingleTapUp--------》onSingleTapConfirmed

时间稍长:onDown--------》onShowPress------》onSingleTapUp--------》onSingleTapConfirmed

2. 长按事件

onDown--------》onShowPress------》onLongPress

3.抛:手指触动屏幕后,稍微滑动后立即松开

onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling

4.拖动

onDown------》onScroll----》onScroll------》onFiling

注意:有的时候会触发onFiling,但是有的时候不会触发,个人理解是人的动作不标准所致。