一、如果使用者在獲得焦點的VIEW上按KEYCODE_DPAD_CENTER或KEYCODE_ENTER鍵,即OK鍵後,在VIEW的onKeyDown方法中會開啟一個延遲線程,在延遲線程中會去回調onLongClick()方法,代碼如下:
在如下代碼中開始延遲線程:
[java] view plain copy print ? 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; }
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; }
延遲線程代碼如下:
[java] view plain copy print ? 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; } }
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事件中:
[java] view plain copy print ? case MotionEvent.ACTION_DOWN: if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } mPrivateFlags |= PREPRESSED; mHasPerformedLongPress = false; postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());//開始延遲線程檢測觸摸點移動沒 break;
case MotionEvent.ACTION_DOWN: if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } mPrivateFlags |= PREPRESSED; mHasPerformedLongPress = false; postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());//開始延遲線程檢測觸摸點移動沒 break;
如果沒有移動,則會開啟一個延遲線程回調onLongClick()方法:
[java] view plain copy print ? private final class CheckForTap implements Runnable { public void run() { mPrivateFlags &= ~PREPRESSED; mPrivateFlags |= PRESSED; refreshDrawableState(); if ((mViewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) { postCheckForLongClick(ViewConfiguration.getTapTimeout());//開啟延遲線程回調onLongClick()方法 } } }
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毫秒