android View中如何判斷長按事件
一、如果用戶在獲得焦點的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;
- }
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;
- }
- }
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事件中:
- 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()方法:
- 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毫秒
最後更新:2017-04-02 16:48:03