Android 触摸及手势操作GestureDetector

触摸屏为我们操作无键盘、无鼠标的手机系统带来了很多的便利。当用户触摸屏幕时会产生很多的触摸事件,down、up、move等等。一个最简单的屏幕触摸动作触发了一系列Touch事件:ACTION_DOWN->ACTION_MOVE->ACTION_MOVE->ACTION_MOVE...->ACTION_MOVE->ACTION_UP .    View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,如下:

public class MainActivity extends Activity {  
@Override  
public boolean onTouchEvent(MotionEvent event){   
         
    int action = MotionEventCompat.getActionMasked(event);  
         
    switch(action) {  
        case (MotionEvent.ACTION_DOWN) :  
            Log.d(DEBUG_TAG,"Action was DOWN");  
            return true;  
        case (MotionEvent.ACTION_MOVE) :  
            Log.d(DEBUG_TAG,"Action was MOVE");  
            return true;  
        case (MotionEvent.ACTION_UP) :  
            Log.d(DEBUG_TAG,"Action was UP");  
            return true;  
        case (MotionEvent.ACTION_CANCEL) :  
            Log.d(DEBUG_TAG,"Action was CANCEL");  
            return true;  
        case (MotionEvent.ACTION_OUTSIDE) :  
            Log.d(DEBUG_TAG,"Movement occurred outside bounds " +  
                    "of current screen element");  
            return true;        
        default :   
            return super.onTouchEvent(event);  
    }        
}  
 OnTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势。  

public class GestureDetector extends Object   

java.lang.Object

android.view.GestureDetector

    GestureDetector属于android.view包,android还提供了android.gesture包支持更多的手势操作,以后我们会介绍到。官方的介绍中使用了GestureDetectorCompat处理手势识别,为什么使用GestureDetectorCompat替换了GestureDetector呢,官方的是这样解释的:


  GestureDetectorCompat实例化有下面两种方法:

GestureDetector类对外提供了两个接口:OnGestureListener,OnDoubleTapListener,还有一个内部类SimpleOnGestureListener;SimpleOnGestureListener类是GestureDetector提供给我们的一个更方便的响应不同手势的类,它实现了上述两个接口,该类是static class,也就是说它实际上是一个外部类,我们可以在外部继承这个类,重写里面的手势处理方法。因此实现手势识别有两种方法,一种实现OnGestureListener接口,另一种是使用SimpleOnGestureListener类。

OnGestureListener有下面的几个动作:
按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。

抛掷(onFling): 手指在触摸屏上迅速移动,并松开的动作。

长按(onLongPress): 手指按在持续一段时间,并且没有松开。

滚动(onScroll): 手指在触摸屏上滑动。

按住(onShowPress): 手指按在触摸屏上,它的时间范围在按下起效,在长按之前。

抬起(onSingleTapUp):手指离开触摸屏的那一刹那。
 使用OnGestureListener接口,这样需要重载OnGestureListener接口所有的方法,适合监听所有的手势,正如官方文档提到的“Detecing All Supported Gestures”。
public class MainActivity extends Activity implements   
        GestureDetector.OnGestureListener,  
        GestureDetector.OnDoubleTapListener{  
      
    private static final String DEBUG_TAG = "Gestures";  
    private GestureDetectorCompat mDetector;   
  
    // Called when the activity is first created.   
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        // Instantiate the gesture detector with the  
        // application context and an implementation of  
        // GestureDetector.OnGestureListener  
        mDetector = new GestureDetectorCompat(this,this);  
        // Set the gesture detector as the double tap  
        // listener.  
        mDetector.setOnDoubleTapListener(this);  
    }  
  
    @Override   
    public boolean onTouchEvent(MotionEvent event){   
        this.mDetector.onTouchEvent(event);  
        // Be sure to call the superclass implementation  
        return super.onTouchEvent(event);  
    }  
  
    @Override  
    public boolean onDown(MotionEvent event) {   
        Log.d(DEBUG_TAG,"onDown: " + event.toString());   
        return true;  
    }  
  
    @Override  
    public boolean onFling(MotionEvent event1, MotionEvent event2,   
            float velocityX, float velocityY) {  
        Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());  
        return true;  
    }  
  
    @Override  
    public void onLongPress(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onLongPress: " + event.toString());   
    }  
  
    @Override  
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,  
            float distanceY) {  
        Log.d(DEBUG_TAG, "onScroll: " + e1.toString()+e2.toString());  
        return true;  
    }  
  
    @Override  
    public void onShowPress(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onShowPress: " + event.toString());  
    }  
  
    @Override  
    public boolean onSingleTapUp(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onSingleTapUp: " + event.toString());  
        return true;  
    }  
  
    @Override  
    public boolean onDoubleTap(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onDoubleTap: " + event.toString());  
        return true;  
    }  
  
    @Override  
    public boolean onDoubleTapEvent(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onDoubleTapEvent: " + event.toString());  
        return true;  
    }  
  
    @Override  
    public boolean onSingleTapConfirmed(MotionEvent event) {  
        Log.d(DEBUG_TAG, "onSingleTapConfirmed: " + event.toString());  
        return true;  
    }  
}  
这样会造成有些手势动作我们用不到,但是还要重载。SimpleOnGestureListener类的出现为我们解决了这个问题,如果你想“Detecting a Subset of Supported Gestures”,SimpleOnGestureListener是最好的选择。
public class MainActivity extends Activity {   
      
    private GestureDetectorCompat mDetector;   
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        mDetector = new GestureDetectorCompat(this, new MyGestureListener());  
    }  
  
    @Override   
    public boolean onTouchEvent(MotionEvent event){   
        this.mDetector.onTouchEvent(event);  
        return super.onTouchEvent(event);  
    }  
      
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener {  
        private static final String DEBUG_TAG = "Gestures";   
         
        @Override  
        public boolean onDown(MotionEvent event) {   
            Log.d(DEBUG_TAG,"onDown: " + event.toString());   
            return true;  
        }  
  
        @Override  
        public boolean onFling(MotionEvent event1, MotionEvent event2,   
                float velocityX, float velocityY) {  
            Log.d(DEBUG_TAG, "onFling: " + event1.toString()+event2.toString());  
            return true;  
        }  
    }  
}  

 最后了我们也解释两个问题:

    1、onTouchEvent中为什么使用了MotionEventCompat,而不直接使用MotionEvent。因为MotionEventCompat使更多的Action适配到API 4。

    2、Android的view怎么使用手势,方法如下:

View myView = findViewById(R.id.my_view);   
    myView.setOnTouchListener(new OnTouchListener() {  
        public boolean onTouch(View v, MotionEvent event) {  
            // ... Respond to touch events         
            this.mDetector.onTouchEvent(event);  
            return super.onTouchEvent(event);  
        }  
    });  


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值