一、如果用户在获得焦点的VIEW上按KEYCODE_DPAD_CENTER或KEYCODE_ENTER键,即OK键后,在VIEW的onKeyDown方法中会开启一个延迟线程,在延迟线程中会去回调onLongClick()方法,代码如下:
在如下代码中开始延迟线程:
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; }
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中的onTouchEvent中的DOWN事件中:
case MotionEvent.ACTION_DOWN: if (mPendingCheckForTap == null) { mPendingCheckForTap = new CheckForTap(); } mPrivateFlags |= PREPRESSED; mHasPerformedLongPress = false; postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());//开始延迟线程检测触摸点移动没 break;
如果没有移动,则会开启一个延迟线程回调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毫秒