首页 > 移动平台 > 详细

Android自定义长按事件

时间:2014-01-21 23:24:18      阅读:463      评论:0      收藏:0      [点我收藏+]

Android系统自带了长按事件,setOnLongClickListener即可监听。但是有时候,你不希望用系统的长按事件,比如当希望长按的时间更长一点的时候。这时候就需要自己来定义这个长按事件了。
    自定义长按事件的方式:

Java代码  bubuko.com,布布扣
  1. package chroya.fun;  
  2.   
  3. import android.content.Context;  
  4. import android.view.MotionEvent;  
  5. import android.view.View;  
  6. import android.view.ViewConfiguration;  
  7.   
  8. public class LongPressView1 extends View{  
  9.     private int mLastMotionX, mLastMotionY;  
  10.     //是否移动了  
  11.     private boolean isMoved;  
  12.     //是否释放了  
  13.     private boolean isReleased;  
  14.     //计数器,防止多次点击导致最后一次形成longpress的时间变短  
  15.     private int mCounter;  
  16.     //长按的runnable  
  17.     private Runnable mLongPressRunnable;  
  18.     //移动的阈值  
  19.     private static final int TOUCH_SLOP = 20;  
  20.   
  21.     public LongPressView1(Context context) {  
  22.         super(context);  
  23.         mLongPressRunnable = new Runnable() {  
  24.               
  25.             @Override  
  26.             public void run() {  
  27.                 mCounter--;  
  28.                 //计数器大于0,说明当前执行的Runnable不是最后一次down产生的。  
  29.                 if(mCounter>0 || isReleased || isMoved) return;  
  30.                 performLongClick();  
  31.             }  
  32.         };  
  33.     }  
  34.   
  35.     public boolean dispatchTouchEvent(MotionEvent event) {  
  36.         int x = (int) event.getX();  
  37.         int y = (int) event.getY();  
  38.           
  39.         switch(event.getAction()) {  
  40.         case MotionEvent.ACTION_DOWN:  
  41.             mLastMotionX = x;  
  42.             mLastMotionY = y;  
  43.             mCounter++;  
  44.             isReleased = false;  
  45.             isMoved = false;  
  46.             postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout());  
  47.             break;  
  48.         case MotionEvent.ACTION_MOVE:  
  49.             if(isMoved) break;  
  50.             if(Math.abs(mLastMotionX-x) > TOUCH_SLOP   
  51.                     || Math.abs(mLastMotionY-y) > TOUCH_SLOP) {  
  52.                 //移动超过阈值,则表示移动了  
  53.                 isMoved = true;  
  54.             }  
  55.             break;  
  56.         case MotionEvent.ACTION_UP:  
  57.             //释放了  
  58.             isReleased = true;  
  59.             break;  
  60.         }  
  61.         return true;  
  62.     }  
  63. }  

     代码里注释的比较清楚。主要思路是在down的时候,让一个Runnable一段时间后执行,如果时间到了,没有移动超过定义的阈值,也没有释放,则触发长按事件。在真实环境中,当长按触发之后,还需要将后来的move和up事件屏蔽掉。此处是示例,就略去了。

      下面讲讲第二种方式:

Java代码  bubuko.com,布布扣
  1. package chroya.fun;  
  2.   
  3. import android.content.Context;  
  4. import android.view.MotionEvent;  
  5. import android.view.View;  
  6. import android.view.ViewConfiguration;  
  7.   
  8. public class LongPressView2 extends View{  
  9.     private int mLastMotionX, mLastMotionY;  
  10.     //是否移动了  
  11.     private boolean isMoved;  
  12.     //长按的runnable  
  13.     private Runnable mLongPressRunnable;  
  14.     //移动的阈值  
  15.     private static final int TOUCH_SLOP = 20;  
  16.   
  17.     public LongPressView2(Context context) {  
  18.         super(context);  
  19.         mLongPressRunnable = new Runnable() {  
  20.               
  21.             @Override  
  22.             public void run() {               
  23.                 performLongClick();  
  24.             }  
  25.         };  
  26.     }  
  27.   
  28.     public boolean dispatchTouchEvent(MotionEvent event) {  
  29.         int x = (int) event.getX();  
  30.         int y = (int) event.getY();  
  31.           
  32.         switch(event.getAction()) {  
  33.         case MotionEvent.ACTION_DOWN:  
  34.             mLastMotionX = x;  
  35.             mLastMotionY = y;  
  36.             isMoved = false;  
  37.             postDelayed(mLongPressRunnable, ViewConfiguration.getLongPressTimeout());  
  38.             break;  
  39.         case MotionEvent.ACTION_MOVE:  
  40.             if(isMoved) break;  
  41.             if(Math.abs(mLastMotionX-x) > TOUCH_SLOP   
  42.                     || Math.abs(mLastMotionY-y) > TOUCH_SLOP) {  
  43.                 //移动超过阈值,则表示移动了  
  44.                 isMoved = true;  
  45.                 removeCallbacks(mLongPressRunnable);  
  46.             }  
  47.             break;  
  48.         case MotionEvent.ACTION_UP:  
  49.             //释放了  
  50.             removeCallbacks(mLongPressRunnable);  
  51.             break;  
  52.         }  
  53.         return true;  
  54.     }  
  55. }  

     思路跟第一种差不多,不过,在移动超过阈值和释放之后,会将Runnable从事件队列中remove掉,长按事件也就不会再触发了。源码中实现长按的原理也基本如此。

Android自定义长按事件

原文:http://www.cnblogs.com/Free-Thinker/p/3528991.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!