首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android OnClick 與 OnTouch 事件衝突:return false 導致 ACTION_UP 丟失的正確處理模式

     編輯:程式設計綜合問答

事件分發機制回顧

  • dispatchTouchEvent → onInterceptTouchEvent → onTouchEvent
  • View.OnTouchListener.onTouch 優先於 onTouchEvent。
  • onTouch 回傳 true 表示消費事件,**阻斷**後續 onClick。
  • onTouch 回傳 false 表示不消費,**但必須在 ACTION_DOWN 回傳 true 才能收到後續 ACTION_MOVE/UP**。

問題原因

// 錯誤:ACTION_DOWN 回傳 false
@Override
public boolean onTouch(View v, MotionEvent event) {
    return false; // 導致只有 DOWN,沒有 UP,onClick 不觸發
}

正確模式:ACTION_DOWN 回傳 true,其餘 false

button.setOnTouchListener((v, event) -> {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            v.setPressed(true); // 視覺反饋
            return true;        // 關鍵:繼續接收 UP
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            v.setPressed(false);
            // 執行點擊邏輯或讓 onClick 處理
            return false;       // 不消費,傳給 onClick
    }
    return false;
});

button.setOnClickListener(v -> {
    // 正常觸發
});

替代方案:自定義 View 覆寫 onTouchEvent

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        setPressed(true);
        return true;
    } else if (event.getAction() == MotionEvent.ACTION_UP) {
        setPressed(false);
        performClick(); // 觸發 onClick
        return true;
    }
    return super.onTouchEvent(event);
}

總結

OnTouchListener.onTouch 在 ACTION_DOWN **必須回傳 true** 才能接收後續事件並讓 onClick 正常觸發。若需自定義按壓視覺效果,建議覆寫 onTouchEvent 並呼叫 performClick(),最符合 Android 事件分發規範。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved