如何在子檢視組和父檢視組觸控事件之間進行更改

  1. 巢狀檢視組的 onTouchEvents() 可以由 boolean onInterceptTouchEvent 管理。

OnInterceptTouchEvent 的預設值為 false。

父母的 onTouchEvent 是在孩子面前收到的。如果 OnInterceptTouchEvent 返回 false,它會將鏈中的運動事件傳送到子項的 OnTouchEvent 處理程式。如果它返回 true,則父級將處理觸控事件。

但是,可能存在這樣的情況:我們希望某些子元素管理 OnTouchEvents,而某些子元素由父檢視(或可能是父檢視的父節點)管理。

這可以通過多種方式進行管理。

  1. 可以通過實現 requestDisallowInterceptTouchEvent 來保護子元素免受父節點影響的一種方式。

public void requestDisallowInterceptTouchEvent(boolean disallowIntercept)

如果元素啟用了事件處理程式,則可以防止任何父檢視管理此元素的 OnTouchEvent

如果 OnInterceptTouchEvent 為 false,則將評估子元素的 OnTouchEvent。如果處理各種觸控事件的子元素中有方法,則禁用的任何相關事件處理程式都會將 OnTouchEvent 返回給父元素。

這個答案:
觸控事件傳播如何通過的視覺化:
parent -> child|parent -> child|parent -> child views.

StackOverflow 文件 禮貌來自這裡

  1. 另一種方法是從父母的 OnInterceptTouchEvent 返回不同的值。

此示例取自 ViewGroup 中的管理觸控事件 ,演示了在使用者滾動時如何攔截子項的 OnTouchEvent

4A。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    /*
     * This method JUST determines whether we want to intercept the motion.
     * If we return true, onTouchEvent will be called and we do the actual
     * scrolling there.
     */

    final int action = MotionEventCompat.getActionMasked(ev);

    // Always handle the case of the touch gesture being complete.
    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) {
        // Release the scroll.
        mIsScrolling = false;
        return false; // Do not intercept touch event, let the child handle it
    }

    switch (action) {
        case MotionEvent.ACTION_MOVE: {
            if (mIsScrolling) {
                // We're currently scrolling, so yes, intercept the 
                // touch event!
                return true;
            }

            // If the user has dragged her finger horizontally more than 
            // the touch slop, start the scroll

            // left as an exercise for the reader
            final int xDiff = calculateDistanceX(ev); 

            // Touch slop should be calculated using ViewConfiguration 
            // constants.
            if (xDiff > mTouchSlop) { 
                // Start scrolling!
                mIsScrolling = true;
                return true;
            }
            break;
        }
        ...
    }

    // In general, we don't want to intercept touch events. They should be 
    // handled by the child view.
    return false;
}

這是來自同一連結的一些程式碼,顯示如何在元素周圍建立矩形的引數:

4B。

// The hit rectangle for the ImageButton
myButton.getHitRect(delegateArea);
        
// Extend the touch area of the ImageButton beyond its bounds
// on the right and bottom.
delegateArea.right += 100;
delegateArea.bottom += 100;
        
// Instantiate a TouchDelegate.
// "delegateArea" is the bounds in local coordinates of 
// the containing view to be mapped to the delegate view.
// "myButton" is the child view that should receive motion
// events.
TouchDelegate touchDelegate = new TouchDelegate(delegateArea, myButton);
 
// Sets the TouchDelegate on the parent view, such that touches 
// within the touch delegate bounds are routed to the child.
if (View.class.isInstance(myButton.getParent())) {
    ((View) myButton.getParent()).setTouchDelegate(touchDelegate);
}