Activity 佈局包含 TitleBar + RecyclerView。RecyclerView 的 Adapter 為 Item 設置了 OnClickListener。重寫 Activity 的 onTouchEvent(MotionEvent event) 發現**永不執行**。
View 的觸摸事件分發機制: 事件從 Activity dispatchTouchEvent → ViewGroup onInterceptTouchEvent → View onTouchEvent。
**RecyclerView 的 Item 點擊事件消費了觸摸事件**,並返回 true 表示「已處理」,導致事件不再向上傳遞到 Activity 的 onTouchEvent。
@Override
public boolean onTouchEvent(MotionEvent event) {
// 業務邏輯...
// 關鍵:必須返回 true 表示消費事件,false 表示不消費繼續傳遞
// 若想讓 Activity 接收到事件,這裡必須返回 true (或調用 super 返回其結果)
return super.onTouchEvent(event); // 或 return true;
}
**常見錯誤:** 重寫 onTouchEvent 後**忘記返回值**,或誤寫 return false,導致系統認為事件未處理,但實際上 RecyclerView 已消費,Activity 仍收不到。
若需同時支持 Item 點擊與 Activity 級手勢(如滑動返回、全屏手勢),需在分發層協調:
recyclerView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
@Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
// 返回 false 讓事件繼續傳遞給 Item 的 OnClickListener
// 返回 true 攔截事件,Activity 可收到 onTouchEvent
// 這裡可根據手勢類型決定:如雙指手勢攔截,單指放行
return false;
}
@Override public void onTouchEvent(RecyclerView rv, MotionEvent e) {}
@Override public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {}
});
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// 全局手勢識別邏輯
if (gestureDetector.onTouchEvent(ev)) {
return true; // 消費事件,不再分發給子 View
}
return super.dispatchTouchEvent(ev); // 正常分發給 RecyclerView 等
}
| 現象 | 檢查項 | 修正 |
|---|---|---|
| Activity onTouchEvent 執行 | 方法返回值是否為 true / super.onTouchEvent() | 添加 return super.onTouchEvent(event); |
| Item 點擊與手勢衝突 | 是否需同時支持 | 用 OnItemTouchListener 或 dispatchTouchEvent 協調 |
| RecyclerView 滑動不流暢 | onInterceptTouchEvent 邏輯過重 | 保持輕量,避免複雜計算 |
**「低級錯誤,onTouchEvent 的返回值沒有修改」** —— 確保 onTouchEvent 返回 true (或 super.onTouchEvent) 即可讓 Activity 接收觸摸事件。若需複雜手勢協調,請在 dispatchTouchEvent 或 RecyclerView.OnItemTouchListener 層面統一處理分發邏輯。