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

Android HorizontalScrollView 嵌套 ListView 滑動衝突完美解決

     編輯:程式設計綜合問答

HorizontalScrollView (HSV) 包裹 ListView 時,手指稍微偏移 X 軸就觸發水平滑動,導致垂直列表難以滑動。核心思路:垂直滑動時攔截觸摸事件,禁止 HSV 消費。

方案一:自定義 ListView 重寫 onTouchEvent(推薦)

public class VerticalListView extends ListView {
    private int mLastY;

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastY = (int) ev.getY();
                getParent().requestDisallowInterceptTouchEvent(true); // 關鍵:搶奪攔截權
                break;
            case MotionEvent.ACTION_MOVE:
                int deltaY = Math.abs((int) ev.getY() - mLastY);
                if (deltaY > 10) // 垂直位移超過閾值
                    getParent().requestDisallowInterceptTouchEvent(true);
                else
                    getParent().requestDisallowInterceptTouchEvent(false); // 釋放給 HSV
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }
}

方案二:外部攔截法(在 HSV 或父容器)

hsv.setOnTouchListener((v, event) -> {
    if (event.getAction() == MotionEvent.ACTION_MOVE) {
        // 判斷是否為垂直滑動意圖,返回 true 消費事件阻止 HSV 滑動
    }
    return false;
});

關鍵 API

  • requestDisallowInterceptTouchEvent(true):子 View 要求父 View 不得攔截 觸摸事件,強制由子 View 處理。
  • onInterceptTouchEvent:ViewGroup 決定是否攔截事件分發給子 View。

注意事項

  • 閾值 10px 需根據密度調整:dp2px(10)。
  • 若列表項有按鈕/輸入框,需在 ACTION_DOWN 判斷點擊區域,避免誤觸發攔截。
  • Android 5.0+ 推薦用 RecyclerView + NestedScrollingParent 機制,原生支援嵌套滑動協調。

一行 requestDisallowInterceptTouchEvent(true),讓雙向滑動各安其位。

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