zoukankan      html  css  js  c++  java
  • 窗口的基本手势事件处理

    当用户触摸屏幕时会产生很多的触摸事件,down、up、move等等。View类有个View.OnTouchListener内部接口,通过重写他的onTouch(View v, MotionEvent event)方法,我们可以处理一些touch事件,如下是activity的ontouch方法里调用的是super.onTouchEvent(),因此直接覆写onTouchEvent():

    1简单的监听

    public class MainActivity extends Activity {  
    ...  
    // This example shows an Activity, but you would use the same approach if  
    // you were subclassing a View.  
    @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);  
        }        
    }  
    

      (2)复杂监听

      OnTouch提供的事件还是相对较简单,如果需要处理一些复杂的手势,用这个接口就会很麻烦,因为我们要根据用户触摸的轨迹去判断是什么手势。Android sdk给我们提供了GestureDetector(Gesture:手势Detector:识别)类,通过这个类我们可以识别很多的手势。 GestureDetector属于android.view包,android还提供了android.gesture包支持更多的手势操作,以后我们会介绍到。官方的介绍中使用了GestureDetectorCompat处理手势识别,使用GestureDetectorCompat替换。

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

    OnGestureListener有下面的几个动作:

    按下(onDown): 刚刚手指接触到触摸屏的那一刹那,就是触的那一下。

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

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

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

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

    抬起(onSingleTapUp):手指离开触摸屏的那一刹那。

        使用OnGestureListener接口,这样需要重载OnGestureListener接口所有的方法,适合监听所有的手势,正如官方文档提到的“Detecing All Supported Gestures”。值得注意的是:它也是通过覆写onTouchEvent来处理事件的,如果不在onTouchEvent里处理,下面的事件里的System.out.println()是打不出来的,里面的动作也不会执行。

    我的一个demo如下:在双击屏幕时候会拨打电话。

    public class MainActivity extends Activity implements OnGestureListener,OnDoubleTapListener
    {
    	private GestureDetectorCompat mDetector; 
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
             
            mDetector=new GestureDetectorCompat(this,this); 
            mDetector.setOnDoubleTapListener(this);
        }
     
        @Override
        public boolean onTouchEvent(MotionEvent event) {
            //这里面处理GestureDetectorCompat调用listener监听到的事件,若这里不调用下面的这个函数,下面监听到的事件也是不会处理的
        	//就是说GestureDetectorCompat的原理也是调用onTouch来处理的。
        	this.mDetector.onTouchEvent(event);
        	 return super.onTouchEvent(event);  
        }
      
     
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            Log.d("erro", "onSingleTapConfirmed: " + e.toString());
            return true;
        }
     
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            // TODO Auto-generated method stub
            System.out.println("双击了...");
            return true;
        }
     
        @Override
        public boolean onDoubleTapEvent(MotionEvent e) {
        	Intent intent =new Intent();
        	intent.setAction(Intent.ACTION_CALL);
        	intent.setData(Uri.parse("tel:"+15607209));
        	startActivity(intent);
            System.out.println("双击事件完成...");
            return true;
        }
     
        @Override
        public boolean onDown(MotionEvent e) {
            System.out.println("落下屏幕时候...");
            return false;
        }
     
        @Override
        public void onShowPress(MotionEvent e) {
            System.out.println("被按住时...");     
        }
     
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            System.out.println("单击的时候离开屏幕");
            return false;
        }
     
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
                float distanceY) {
            System.out.println("滑动...");
            return true;
        }
     
        @Override
        public void onLongPress(MotionEvent e) {
            System.out.println("长按...");       
        }
     
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            System.out.println("极速滑动...");
            return true;
        }
     
    
    }
    

      总结:上面的demo是利用activity继承了OnGestureListener,OnDoubleTapListener两个接口,在activity里实现了这两个接口,GestureDetectorCompat mDetector在调用监听的事件,然后在activity里的onTouchEvent里调用mDetector的onTouch方法来调用处理监听到的事件(因此点击整个屏幕都可以响应)。若只想点击某一个控件里实现监听事件,则必须在一个控件里调用GestureDetectorCompat 的onTouch事件

    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 onTouchEvent(event);  
            }  
        });  
    

      下面只在一个图文件里监听点击事件:记住覆写Ontouchlistener的onTouch方法,在该方法

    mDetector.onTouchEvent(event);
    return onTouchEvent(event);

    在哪View里调用就在哪个view里面才能监听到该事件。在activity里和一般的view里区别:一般的View在onTouch()里调用onTouchEvent()方法,而activity里直接覆写的onTouchEvent()方法里面返回时候,super.onTouchEvent。

    public class MainActivity extends Activity implements OnGestureListener,OnDoubleTapListener
    {
    	private GestureDetectorCompat mDetector; 
    	private ImageView im;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            im=(ImageView) findViewById(R.id.im);
            im.setOnTouchListener(new OnTouchListener() {
            	@Override
    			public boolean onTouch(View v, MotionEvent event) {
    
    				mDetector.onTouchEvent(event);
    				return onTouchEvent(event);
    			}
    		});
            mDetector=new GestureDetectorCompat(this,this); 
            mDetector.setOnDoubleTapListener(this);
        }
     
        
        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
           system.out.println("单机事件完成");
            return true;
        }
      @Override public boolean onDoubleTap(MotionEvent e) { // TODO Auto-generated method stub System.out.println("双击了..."); return true; } @Override public boolean onDoubleTapEvent(MotionEvent e) { // Intent intent =new Intent(); // intent.setAction(Intent.ACTION_CALL); // intent.setData(Uri.parse("tel:"+15607209)); // startActivity(intent); System.out.println("双击事件完成..."); return true; } @Override public boolean onDown(MotionEvent e) { System.out.println("落下屏幕时候..."); return false; } @Override public void onShowPress(MotionEvent e) { System.out.println("被按住时..."); } @Override public boolean onSingleTapUp(MotionEvent e) { System.out.println("单击的时候离开屏幕"); return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { System.out.println("滑动..."); return true; } @Override public void onLongPress(MotionEvent e) { System.out.println("长按..."); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { System.out.println("极速滑动..."); return true; } }

      就是还有一个问题没解决:其它时间都正常,就是当我双击的时候,一次双击却执行了三次双击的意图,也就是说监听到了3次有时4次onDoubleTapEvent,猜测可能是双击事件完成后不断向activity的ontouch发送这个事件完成,直到onTouch处理后为止。因此在写双击的处理的事件的时候最好写在onDoubleTap方法里。而双击的时候第一次单机完成也会执行onSingleTapUp,因此点击单机事件的时候最好写在:onSingleTapConfirmed

     (3)利用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;  
            }  
        }  
    }  
    

      PS:本文很多地方都参考了:http://blog.csdn.net/xyz_lmn/article/details/16826669

  • 相关阅读:
    css学习之LInk & import
    用javascript制作2048游戏的思路(原创若 转载请附上本链接)
    Sublime Text2中的快捷键一览表(Sublime 键盘快捷键大全 )
    《Scrum实战》第1次课课后任务
    反省读经教育理论的误区 ——关于十三岁之前理解的问题
    王守仁的学前教育思想
    孙氏太极拳--无极桩
    秘静克老人的站桩
    敏捷领域学习规划
    同侪隐修录 (2016-12-25 23:10:21)转载▼
  • 原文地址:https://www.cnblogs.com/bokeofzp/p/4756327.html
Copyright © 2011-2022 走看看