Android Comment varier entre les événements tactiles des groupes de vues enfants et parents


Exemple

  1. onTouchEvents() pour les groupes de vues imbriqués peut être géré par le boolean onInterceptTouchEvent .

La valeur par défaut pour OnInterceptTouchEvent est false.

Le onTouchEvent du onTouchEvent est reçu avant l'enfant. Si OnInterceptTouchEvent renvoie false, il envoie l'événement motion en aval de la chaîne au gestionnaire OnTouchEvent l'enfant. Si elle retourne vrai, le parent va gérer l'événement tactile.

Cependant, il peut y avoir des cas où nous voulons que certains éléments enfants gèrent OnTouchEvent s et que certains soient gérés par la vue parent (ou éventuellement le parent du parent).

Cela peut être géré de plusieurs façons.

  1. Une manière de protéger un élément enfant du OnInterceptTouchEvent du OnInterceptTouchEvent consiste à implémenter le requestDisallowInterceptTouchEvent .

public void requestDisallowInterceptTouchEvent (booléen disallowIntercept)

Cela empêche toute vue parent de gérer le OnTouchEvent pour cet élément si l'élément possède des gestionnaires d'événements activés.

Si le OnInterceptTouchEvent est false, l'élément OnTouchEvent l'élément enfant sera évalué. Si vous avez des méthodes dans les éléments enfants qui gèrent les différents événements tactiles, tous les gestionnaires d'événements liés qui sont désactivés renverront le OnTouchEvent au parent.

Cette réponse:
Une visualisation de la manière dont la propagation des événements tactiles passe:
parent -> child|parent -> child|parent -> child views.

entrer la description de l'image ici Courtoisie d'ici

  1. Une autre méthode consiste à renvoyer des valeurs variables à partir du OnInterceptTouchEvent pour le parent.

Cet exemple, tiré de la gestion des événements tactiles dans un groupe ViewGroup , montre comment intercepter le OnTouchEvent l'enfant lorsque l'utilisateur fait défiler.

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

Ceci est un code du même lien montrant comment créer les paramètres du rectangle autour de votre élément:

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