Was bedeutet der boolesche Wert, der von einer Ereignisbehandlungsmethode in Android zurückgegeben wird?

110

In Android geben die meisten Ereignis-Listener-Methoden einen booleschen Wert zurück. Was bedeutet dieser wahre / falsche Wert? Was wird es zu den Subsequenzereignissen führen?

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

In Bezug auf das obige Beispiel habe ich festgestellt, dass jedes Berührungsereignis (DOWN, UP, MOVE usw.) gemäß meiner logView erfasst wurde , wenn in der onTouch- Methode true zurückgegeben wurde . Im Gegenteil, wenn return false ist, wurde nur das DOWN-Ereignis erfasst. Es scheint also, dass return false die Ausbreitung des Ereignisses verhindert. Hab ich recht ?

Darüber hinaus müssen in einem OnGestureListener viele Methoden auch einen booleschen Wert zurückgeben. Haben sie die gleiche Bedeutung?

John Wang
quelle

Antworten:

140

Wenn Sie truevon einem ACTION_DOWNEreignis zurückkehren, interessieren Sie sich für den Rest der Ereignisse in dieser Geste. Eine "Geste" bedeutet in diesem Fall alle Ereignisse bis zum Finale ACTION_UPoder ACTION_CANCEL. Wenn Sie falsevon einem ACTION_DOWNMittel zurückkehren, das Sie nicht möchten, haben andere Ansichten die Möglichkeit, es zu verarbeiten. Wenn Sie überlappende Ansichten haben, kann dies eine Geschwisteransicht sein. Wenn nicht, sprudelt es zum Elternteil.

adamp
quelle
3
adamp, gibt es eine Möglichkeit, weiterhin Ereignisse zu empfangen UND die Ereignisse durchzulassen?
Ticofab
@ticofab Nein, nur ein übergeordnetes Element der Ansicht, die derzeit Ereignisse empfängt, kann zukünftige Ereignisse in der Geste abfangen. (Natürlich können Sie jederzeit Ihre eigenen Umleitungssysteme in einer übergeordneten Ansicht erstellen, aber ich würde es nicht empfehlen, es sei denn, Sie wissen wirklich, was Sie tun. :))
adamp
@adamp Ich kann mir nicht vorstellen, warum onTouch 2 Mal aufgerufen wird, wenn true zurückgegeben wird, und 1 Mal, wenn false zurückgegeben wird.
Bhargav Jhaveri
1
@adamp: Ich gebe false von ACTION_DOWN zurück, aber mein ACTION_UP wird ausgelöst und ausgeführt.
Mahantesh M Ambi
Verstehe ich diese Antwort falsch oder sind alle anderen ... Diese Antwort besagt, dass return true bedeutet, dass ein hartes Ereignis nicht verbraucht wird. Aber die Wahrheit ist völlig umgekehrt.
Kai Wang
12

Der boolesche Wert bestimmt, ob das Ereignis verbraucht wird oder nicht.

Ja, du hast recht. Wenn Sie false zurückgeben, behandelt der nächste Listener das Ereignis. Wenn true zurückgegeben wird, wird das Ereignis von Ihrem Listener verwendet und nicht an die nächste Methode gesendet.

Falmarri
quelle
2
Das ist falsch. truebedeutet, dass Sie das Ereignis konsumiert haben und den Rest der Ereignisse in der Geste haben möchten - andere Listener / Ansichten erhalten die Ereignisse nicht. falsebedeutet, dass jemand anderes das Ereignis behandelt. Es ist tatsächlich ein bisschen spezifischer als das; siehe meine Antwort.
Adamp
Wie ist das nicht genau das, was ich gesagt habe?
Falmarri
1
Was Sie gesagt haben, ist umgekehrt. :)
Adamp
4

Alle obigen Antworten sind korrekt, aber das Ergebnis ist unterschiedlich, ob die Ansicht ist clickableoder nichtclickable

Beispiel , ich habe eine LinearLayoutenthält 1 Buttonund 1 TextViewwie diese

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

In Aktivität habe ich Code wie

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

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

Klicken Sie auf die Schaltfläche

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

Klicken Sie auf TextView

TAG: TextView onTouch eventDOWN
TAG: LinearLayout onTouch eventDOWN

Klicken Sie auf LinearLayout

TAG: LinearLayout onTouch eventDOWN

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

Klicken Sie auf die Schaltfläche

Similar to case 1

Klicken Sie auf TextView

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

Klicken Sie auf LinearLayout

Similar to case 1

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

Klicken Sie auf die Schaltfläche

Similar to case 1

Klicken Sie auf TextView

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

Klicken Sie auf LinearLayout

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

Hinweis

  • Die Standardeinstellung TextViewist not clickable, es wird anklickbar, wenn wir android:clickable="true"in XML setzen ODER wenn wir setzentextView.setOnClickListener(...)
  • Wenn Sie debuggen, event MOVEkönnen Sie mehr als mein Protokoll aufrufen (es hängt davon ab, wie Sie tippen).

Zusammenfassung

  • onTouchZurück trueoder Ansicht ist clickable , Ansicht erhält alle onTouchEvent
  • onTouchZurück falseund Ansicht ist nicht clickable, Ansicht erhält NEXT onTouchEvent nicht (das übergeordnete Element kann es erhalten)

Hoffe es hilft
DEMO

Phan Van Linh
quelle
1
Dies sollte die Antwort sein! Vielen Dank für eine so ausführliche Erklärung
Mysterious_android
1

Ich habe fast einen Tag bei der Fehlerbehebung verloren, aber ich habe herausgefunden, dass meine onTouch-Funktion 2 Mal aufgerufen wird, wenn true verwendet wird, und 1 Mal, wenn false verwendet wird.

Kamor
quelle
Könnten Sie den Grund herausfinden?
Bhargav Jhaveri
Überprüfen Sie die, event.getAction()weil, wenn Sie falseauf ACTION_DOWN Ereignis zurückkehren, ACTION_UP Ereignis vom Listener ignoriert wird
doodeec
0

Aus dem Android-Dokument :

Hinweis: Android ruft zuerst Ereignishandler und dann die entsprechenden Standardhandler aus der Klassendefinition auf. Wenn Sie von diesen Ereignis-Listenern true zurückgeben, wird die Weitergabe des Ereignisses an andere Ereignis-Listener gestoppt und der Rückruf an den Standardereignishandler in der Ansicht blockiert. Stellen Sie also sicher, dass Sie das Ereignis beenden möchten, wenn Sie true zurückgeben.

Huy Nguyen
quelle