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?
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.
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.
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.
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"
}
}
}
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
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
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
TextView
est not clickable
, elle deviendra cliquable si nous définissons Android:clickable="true"
dans XML OU lorsque nous définissons textView.setOnClickListener(...)
event MOVE
peut appeler plus que mon journal (cela dépend de la façon dont vous tapez)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
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.
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.