Szukaj…


Jak zmieniać zdarzenia dotyku w grupie dzieci i rodziców

  1. onTouchEvents() dla zagnieżdżonych grup widoków może być zarządzany przez wartość boolean onInterceptTouchEvent .

Wartość domyślna dla OnInterceptTouchEvent to false.

onTouchEvent rodzica jest odbierany przed dzieckiem. Jeśli OnInterceptTouchEvent zwraca false, wysyła zdarzenie motion w dół łańcucha do procedury obsługi OnTouchEvent dziecka. Jeśli zwróci wartość true, rodzic zajmie się zdarzeniem dotykowym.

Mogą jednak wystąpić sytuacje, w których chcemy, aby niektóre elementy potomne zarządzały OnTouchEvent a niektóre były zarządzane przez widok nadrzędny (lub ewentualnie nadrzędny element nadrzędny).

Można to zarządzać na więcej niż jeden sposób.

  1. Jednym ze sposobów ochrony elementu potomnego przed OnInterceptTouchEvent rodzica jest implementacja requestDisallowInterceptTouchEvent .

public void requestDisallowInterceptTouchEvent (boolean disallowIntercept)

Zapobiega to zarządzaniu OnTouchEvent przez ten widok nadrzędny dla tego elementu, jeśli element ma włączone procedury obsługi zdarzeń.

Jeśli wartość OnInterceptTouchEvent ma wartość false, wartość OnTouchEvent elementu OnTouchEvent zostanie oceniona. Jeśli masz metody w elementach potomnych obsługujących różne zdarzenia dotykowe, wszelkie powiązane funkcje obsługi zdarzeń, które zostaną wyłączone, zwrócą OnTouchEvent do elementu nadrzędnego.

Ta odpowiedź:
Wizualizacja tego, jak przebiega propagacja zdarzeń dotykowych:
parent -> child|parent -> child|parent -> child views.

wprowadź opis zdjęcia tutaj Dzięki uprzejmości stąd

  1. Innym sposobem jest zwracanie różnych wartości z OnInterceptTouchEvent dla elementu nadrzędnego.

Ten przykład pochodzi z zarządzania zdarzeniami dotykowymi w grupie ViewGroup i pokazuje, jak przechwycić OnTouchEvent dziecka, gdy użytkownik przewija.

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;
}

To jest kod z tego samego linku pokazujący, jak utworzyć parametry prostokąta wokół twojego elementu:

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);
}


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow