閱讀361 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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.    }  
 public boolean onKeyDown(int keyCode, KeyEvent event) {
        boolean result = false;

        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_CENTER:
            case KeyEvent.KEYCODE_ENTER: {
                if ((mViewFlags & ENABLED_MASK) == DISABLED) {
                    return true;
                }
                // Long clickable items don't necessarily have to be clickable
                if (((mViewFlags & CLICKABLE) == CLICKABLE ||
                        (mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) &&
                        (event.getRepeatCount() == 0)) {
                    setPressed(true);
                    if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
                        postCheckForLongClick(0);//在這裏開啟延遲線程
                    }
                    return true;
                }
                break;
            }
        }
        return result;
    }


延遲線程代碼如下:

  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.     }  
class CheckForLongPress implements Runnable {

        private int mOriginalWindowAttachCount;

        public void run() {
            if (isPressed() && (mParent != null)
                    && mOriginalWindowAttachCount == mWindowAttachCount) {
                if (performLongClick()) { //這裏回調onLongClick()方法
                    mHasPerformedLongPress = true;
                }
            }
        }

        public void rememberWindowAttachCount() {
            mOriginalWindowAttachCount = mWindowAttachCount;
        }
    }

二、如果用戶在觸摸屏上長按某個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;  
case MotionEvent.ACTION_DOWN:
                    if (mPendingCheckForTap == null) {
                        mPendingCheckForTap = new CheckForTap();
                    }
                    mPrivateFlags |= PREPRESSED;
                    mHasPerformedLongPress = false;
                    postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());//開始延遲線程檢測觸摸點移動沒
                    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.    }  
 private final class CheckForTap implements Runnable {
        public void run() {
            mPrivateFlags &= ~PREPRESSED;
            mPrivateFlags |= PRESSED;
            refreshDrawableState();
            if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) {
                postCheckForLongClick(ViewConfiguration.getTapTimeout());//開啟延遲線程回調onLongClick()方法
            }
        }
    }

剩下來就和按鍵長按一樣的處理了。


在其中要注意二個參數:

ViewConfiguration.getTapTimeout() 是用於檢測觸摸點有沒有移動的時間,默認為115毫秒

 ViewConfiguration.getLongPressTimeout() 是用於檢測是不是長按的時間,默認為500毫秒

最後更新:2017-04-02 16:48:03

  上一篇:go java在CPU中的一些個破事
  下一篇:go LINUX MAN 命令的使用