Android View中如何判断长按事件


一、如果用户在获得焦点的VIEW上按KEYCODE_DPAD_CENTER或KEYCODE_ENTER键,即OK键后,在VIEW的onKeyDown方法中会开启一个延迟线程,在延迟线程中会去回调onLongClick()方法,代码如下:

在如下代码中开始延迟线程:

  1. public boolean onKeyDown(int keyCode, KeyEvent event) {  
  2.        boolean result = false;  
  3.   
  4.        switch (keyCode) {  
  5.            case KeyEvent.KEYCODE_DPAD_CENTER:  
  6.            case KeyEvent.KEYCODE_ENTER: {  
  7.                if ((mViewFlags & ENABLED_MASK) == DISABLED) {  
  8.                    return true;  
  9.                }  
  10.                // Long clickable items don't necessarily have to be clickable   
  11.                if (((mViewFlags & CLICKABLE) == CLICKABLE ||  
  12.                        (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&  
  13.                        (event.getRepeatCount() == 0)) {  
  14.                    setPressed(true);  
  15.                    if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {  
  16.                        postCheckForLongClick(0);//在这里开启延迟线程   
  17.                    }  
  18.                    return true;  
  19.                }  
  20.                break;  
  21.            }  
  22.        }  
  23.        return result;  
  24.    }  

延迟线程代码如下:

  1. class CheckForLongPress implements Runnable {  
  2.   
  3.         private int mOriginalWindowAttachCount;  
  4.   
  5.         public void run() {  
  6.             if (isPressed() && (mParent != null)  
  7.                     && mOriginalWindowAttachCount == mWindowAttachCount) {  
  8.                 if (performLongClick()) { //这里回调onLongClick()方法   
  9.                     mHasPerformedLongPress = true;  
  10.                 }  
  11.             }  
  12.         }  
  13.   
  14.         public void rememberWindowAttachCount() {  
  15.             mOriginalWindowAttachCount = mWindowAttachCount;  
  16.         }  
  17.     }  
二、如果用户在触摸屏上长按某个VIEW,VIEW中首先会检测在这个触摸点移动没,如果没有移动再开启一个延迟线程去回调onLongClick()方法,代码如下:

在View中的onTouchEvent中的DOWN事件中:

  1. case MotionEvent.ACTION_DOWN:  
  2.                     if (mPendingCheckForTap == null) {  
  3.                         mPendingCheckForTap = new CheckForTap();  
  4.                     }  
  5.                     mPrivateFlags |= PREPRESSED;  
  6.                     mHasPerformedLongPress = false;  
  7.                     postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());//开始延迟线程检测触摸点移动没   
  8.                     break;  

如果没有移动,则会开启一个延迟线程回调onLongClick()方法:

  1. private final class CheckForTap implements Runnable {  
  2.        public void run() {  
  3.            mPrivateFlags &= ~PREPRESSED;  
  4.            mPrivateFlags |= PRESSED;  
  5.            refreshDrawableState();  
  6.            if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {  
  7.                postCheckForLongClick(ViewConfiguration.getTapTimeout());//开启延迟线程回调onLongClick()方法   
  8.            }  
  9.        }  
  10.    }  
剩下来就和按键长按一样的处理了。

在其中要注意二个参数:

ViewConfiguration.getTapTimeout() 是用于检测触摸点有没有移动的时间,默认为115毫秒

 ViewConfiguration.getLongPressTimeout() 是用于检测是不是长按的时间,默认为500毫秒

相关内容