web-dev-qa-db-fra.com

Quelle est la signification de la valeur booléenne renvoyée par une méthode de gestion des événements dans Android

Sous Android, la plupart des méthodes d'écoute d'événements renvoient une valeur booléenne. Quelle est cette valeur vraie/fausse? qu'est-ce que cela va donner aux événements suivants?

class MyTouchListener implements OnTouchListener {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        logView.showEvent(event);
        return true;
    }
}

En ce qui concerne l'exemple ci-dessus, si return true dans onTouch method, j'ai trouvé que chaque événement tactile (DOWN, UP, MOVE, etc.) a été capturé conformément à mon logView . Au contraire, si return est false, seul l'événement DOWN est capturé. Il semble donc que return false empêchera la propagation de l'événement. Ai-je raison ?

De plus, dans OnGestureListener , de nombreuses méthodes doivent également renvoyer une valeur booléenne. Ont-ils le même sens?

99
John Wang

Si vous renvoyez true à partir d'un événement ACTION_DOWN, le reste des événements de ce geste vous intéresse. Un "geste" dans ce cas signifie tous les événements jusqu'au ACTION_UP ou au ACTION_CANCEL final. Le renvoi de false à partir d'un ACTION_DOWN signifie que vous ne voulez pas que l'événement se produise et que d'autres vues puissent le gérer. Si vous avez des vues qui se chevauchent, il peut s'agir d'une vue parentale. Si ce n'est pas le cas, cela va bouillonner jusqu'au parent.

127
adamp

De la documentation: http://developer.Android.com/reference/Android/view/View.OnTouchListener.html#onTouch(Android.view.View , Android.view.MotionEvent)

"Vrai si l'auditeur a consommé l'événement, faux sinon."

Si vous renvoyez true, l'événement est traité. Si false, il ira à la couche suivante.

22
Matthieu

La valeur booléenne détermine si l'événement est consommé ou non.

Oui tu as raison. Si vous renvoyez false, l'écouteur suivant gère l'événement. S'il renvoie true, l'événement est consommé par votre écouteur et n'est pas envoyé à la méthode suivante.

11
Falmarri

La réponse ci-dessus est correcte, mais le résultat est différent si la vue est clickable ou non clickable

Exemple, j'ai une LinearLayout contient 1 Button et 1 TextView comme ceci

<LinearLayout
    Android:id="@+id/linearlayout_root"
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:background="#0aa"
    Android:orientation="vertical">

    <Button
        Android:id="@+id/button_click"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:padding="40dp"
        Android:text="Button Click"
        Android:textSize="20sp" />

    <TextView
        Android:id="@+id/textview_click"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:padding="40dp"
        Android:text="TextView Click"
        Android:textSize="20sp"
        Android:background="#e4e4e4"
        />

</LinearLayout>

En activité, j'ai un code comme

class MainActivity : AppCompatActivity() {
    val TAG = "TAG"

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<LinearLayout>(R.id.linearlayout_root).setOnTouchListener { v, event ->
            Log.i(TAG, "LinearLayout onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<Button>(R.id.button_click).setOnTouchListener { v, event ->
            Log.i(TAG, "Button onTouch event " + getDisplayAction(event.action))
            false
        }

        findViewById<TextView>(R.id.textview_click).setOnTouchListener { v, event ->
            Log.i(TAG, "TextView onTouch event " + getDisplayAction(event.action))
            false
        }
    }

    private fun getDisplayAction(action: Int): String {
        return when (action) {
            MotionEvent.ACTION_DOWN -> "DOWN"
            MotionEvent.ACTION_MOVE -> "MOVE"
            MotionEvent.ACTION_UP -> "UP"
            MotionEvent.ACTION_CANCEL -> "CANCEL"
            MotionEvent.ACTION_OUTSIDE -> "OUTSIDE"
            else -> "UNKNOWN"
        }
    }
}

Cas 1 Linear onTouch return **FALSE**, Button onTouch return **FALSE**, TextView onTouch return **FALSE**

Cliquez sur le bouton

I/TAG: Button onTouch eventDOWN
I/TAG: Button onTouch eventMOVE
I/TAG: Button onTouch eventUP

Cliquez sur TextView

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

Cliquez sur LinearLayout

TAG: LinearLayout onTouch eventDOWN

Cas 2 Linear onTouch return **FALSE**, Button onTouch return **TRUE**, TextView onTouch return **TRUE**

Cliquez sur le bouton

Similar to case 1

Cliquez sur TextView

TAG: TextView onTouch event DOWN
TAG: TextView onTouch event MOVE
TAG: TextView onTouch event UP

Cliquez sur LinearLayout

Similar to case 1

Cas 3 Linear onTouch return **TRUE**, Button onTouch return **FALSE**, TextView onTouch return **FALSE**

Cliquez sur le bouton

Similar to case 1

Cliquez sur TextView

TAG: TextView onTouch event DOWN
TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

Cliquez sur LinearLayout

TAG: LinearLayout onTouch event DOWN
TAG: LinearLayout onTouch event MOVE
TAG: LinearLayout onTouch event UP

Remarque

  • La valeur par défaut de TextView est not clickable, elle deviendra cliquable si nous définissons Android:clickable="true" dans XML OU lorsque nous définissons textView.setOnClickListener(...)
  • Lorsque vous déboguez, event MOVE peut appeler plus que mon journal (cela dépend de la façon dont vous tapez)

Résumé

  • onTouch return true ou la vue est clickable, La vue recevra toutonTouchEvent
  • onTouch return false et la vue n'est pas clickable, la vue ne recevra pas NEXT onTouchEvent (son parent pourrait le recevoir)

J'espère que ça aide
DEMO

2
Linh

J'ai perdu presque une journée de dépannage, mais j'ai quand même découvert que ma fonction onTouch est appelée 2 fois lorsque vous utilisez true et 1 fois lorsque vous utilisez false.

1
kamor

De Android-document

Remarque: Android appelle d'abord les gestionnaires d'événements, puis les gestionnaires par défaut appropriés à partir de la définition de classe. En tant que tel, renvoyer true à partir de ces écouteurs d'événement arrêtera la propagation de l'événement vers d'autres écouteurs d'événement et bloquera également le rappel au gestionnaire d'événements par défaut dans la vue. Assurez-vous donc que vous souhaitez mettre fin à l'événement lorsque vous renvoyez true.

0
Brasc elok