Eingabeereignisse – Übersicht

Schreiben Sie jetzt
Jetpack Compose ist das empfohlene UI-Toolkit für Android. Weitere Informationen zur Verwendung von Berührungen und Eingaben in „Schreiben“

Unter Android gibt es mehrere Möglichkeiten, die Ereignisse aus der Interaktion eines Nutzers mit Ihrer App abzufangen. Wenn Sie die Ereignisse in Ihrer Benutzeroberfläche berücksichtigen, besteht der Ansatz darin, die Ereignisse aus dem spezifischen View-Objekt zu erfassen, mit dem der Nutzer interagiert. Die View-Klasse bietet die Möglichkeit dazu.

In den verschiedenen View-Klassen, die Sie zum Erstellen Ihres Layouts verwenden, sehen Sie vielleicht mehrere öffentliche Callback-Methoden, die für UI-Ereignisse nützlich sind. Diese Methoden werden vom Android-Framework aufgerufen, wenn die jeweilige Aktion für das Objekt ausgeführt wird. Wenn beispielsweise eine Ansicht (z. B. eine Schaltfläche) berührt wird, wird für dieses Objekt die Methode onTouchEvent() aufgerufen. Um dies jedoch abzufangen, müssen Sie die Klasse erweitern und die Methode überschreiben. Es wäre jedoch nicht praktikabel, jedes View-Objekt zu erweitern, um ein solches Ereignis zu verarbeiten. Aus diesem Grund enthält die View-Klasse auch eine Sammlung verschachtelter Schnittstellen mit Callbacks, die Sie viel einfacher definieren können. Diese Oberflächen, die als Event-Listener bezeichnet werden, sind Ihr Ticket zum Erfassen der Nutzerinteraktion mit Ihrer UI.

Die Event-Listener werden zwar häufiger verwendet, um auf Nutzerinteraktionen zu warten, es kann jedoch Situationen geben, in denen Sie eine View-Klasse erweitern möchten, um eine benutzerdefinierte Komponente zu erstellen. Vielleicht möchten Sie die Button-Klasse erweitern, um etwas Ausgefallener zu gestalten. In diesem Fall können Sie das Standardverhalten von Ereignissen für Ihre Klasse mithilfe der Klasse Event-Handler definieren.

Event-Listener

Ein Event-Listener ist eine Schnittstelle in der Klasse View, die eine einzelne Callback-Methode enthält. Diese Methoden werden vom Android-Framework aufgerufen, wenn die Ansicht, unter der der Listener registriert wurde, durch eine Nutzerinteraktion mit dem Element in der UI ausgelöst wird.

In den Ereignis-Listener-Oberflächen sind folgende Callback-Methoden enthalten:

onClick()
Ab View.OnClickListener. Diese Methode wird aufgerufen, wenn der Nutzer das Element entweder berührt (im Touch-Modus) oder den Fokus mit den Navigationstasten oder dem Trackball auf das Element legt und die entsprechende Eingabetaste drückt oder den Trackball nach unten drückt.
onLongClick()
Ab View.OnLongClickListener. Diese Funktion wird aufgerufen, wenn der Nutzer das Element entweder berührt und hält (im Touch-Modus) oder wenn der Nutzer das Element mit den Navigationstasten oder dem Trackball in den Fokus rückt und die entsprechende Eingabetaste drückt und den Trackball hält (eine Sekunde lang).
onFocusChange()
Ab View.OnFocusChangeListener. Dieses wird aufgerufen, wenn der Nutzer mithilfe der Navigationstasten oder des Trackballs zum oder von dem Element navigiert.
onKey()
Ab View.OnKeyListener. Dieser wird aufgerufen, wenn sich der Nutzer auf den Artikel konzentriert und einen Hardwareschlüssel auf dem Gerät drückt oder wieder loslässt.
onTouch()
Ab View.OnTouchListener. Dieses Ereignis wird aufgerufen, wenn der Nutzer eine Aktion ausführt, die als Touch-Ereignis qualifiziert ist, z. B. Drücken, Loslassen oder eine Bewegungsgeste auf dem Bildschirm (innerhalb der Grenzen des Elements).
onCreateContextMenu()
Ab View.OnCreateContextMenuListener. Dieses wird aufgerufen, wenn ein Kontextmenü erstellt wird (infolge eines andauernden "langen Klicks"). Weitere Informationen finden Sie im Entwicklerleitfaden zu Menüs.

Diese Methoden sind die einzigen Bewohner ihrer jeweiligen Benutzeroberfläche. Um eine dieser Methoden zu definieren und deine Ereignisse zu verarbeiten, implementiere die verschachtelte Schnittstelle in deiner Activity-Klasse oder definiere sie als anonyme Klasse. Übergeben Sie dann eine Instanz Ihrer Implementierung an die entsprechende View.set...Listener()-Methode. Rufe beispielsweise setOnClickListener() auf und übergib deine Implementierung von OnClickListener.

Das folgende Beispiel zeigt, wie ein On-Click-Listener für eine Schaltfläche registriert wird.

Kotlin

protected void onCreate(savedValues: Bundle) {
    ...
    val button: Button = findViewById(R.id.corky)
    // Register the onClick listener with the implementation above
    button.setOnClickListener { view ->
        // do something when the button is clicked
    }
    ...
}

Java

// Create an anonymous implementation of OnClickListener
private OnClickListener corkyListener = new OnClickListener() {
    public void onClick(View v) {
      // do something when the button is clicked
    }
};

protected void onCreate(Bundle savedValues) {
    ...
    // Capture our button from layout
    Button button = (Button)findViewById(R.id.corky);
    // Register the onClick listener with the implementation above
    button.setOnClickListener(corkyListener);
    ...
}

Möglicherweise finden Sie es auch praktischer, OnClickListener als Teil Ihrer Activity zu implementieren. Dadurch werden zusätzliche Klassenlasten und Objektzuweisungen vermieden. Beispiel:

Kotlin

class ExampleActivity : Activity(), OnClickListener {
  
    protected fun onCreate(savedValues: Bundle) {
        val button: Button = findViewById(R.id.corky)
        button.setOnClickListener(this)
    }

    // Implement the OnClickListener callback
    fun onClick(v: View) {
        // do something when the button is clicked
    }
}

Java

public class ExampleActivity extends Activity implements OnClickListener {
    protected void onCreate(Bundle savedValues) {
        ...
        Button button = (Button)findViewById(R.id.corky);
        button.setOnClickListener(this);
    }

    // Implement the OnClickListener callback
    public void onClick(View v) {
      // do something when the button is clicked
    }
    ...
}

Beachten Sie, dass der onClick()-Callback im obigen Beispiel keinen Rückgabewert hat. Einige andere Event-Listener-Methoden müssen jedoch einen booleschen Wert zurückgeben. Der Grund hängt vom Ereignis ab. Hier der Grund für die wenigen, die dies tun:

  • onLongClick(): gibt einen booleschen Wert zurück, der angibt, ob das Ereignis verarbeitet wurde und nicht weitergeführt werden soll. Geben Sie also true zurück, um anzugeben, dass Sie das Ereignis verarbeitet haben und es hier beendet werden soll. Wenn Sie es noch nicht verarbeitet haben, wird false zurückgegeben und/oder das Ereignis sollte an andere On-Click-Listener weitergegeben werden.
  • onKey(): gibt einen booleschen Wert zurück, der angibt, ob das Ereignis verarbeitet wurde und nicht weitergeführt werden soll. Geben Sie also true zurück, um anzugeben, dass Sie das Ereignis verarbeitet haben und es hier beendet werden soll. Wenn Sie es noch nicht verarbeitet haben, wird false zurückgegeben und/oder das Ereignis sollte an andere schlüsselgebundene Listener übergeben werden.
  • onTouch(): Gibt einen booleschen Wert zurück, der angibt, ob der Listener dieses Ereignis verarbeitet. Wichtig ist, dass dieses Ereignis mehrere aufeinanderfolgende Aktionen haben kann. Wenn Sie also beim Empfang des Ereignisses der Abwärtsaktion false zurückgeben, geben Sie an, dass Sie das Ereignis nicht verarbeitet haben und auch nicht an nachfolgenden Aktionen aus diesem Ereignis interessiert sind. Daher werden Sie nicht für andere Aktionen innerhalb des Ereignisses aufgerufen, z. B. eine Fingergeste oder das letztendliche Aufwärtsaktionsereignis.

Hardware-Schlüsselereignisse werden immer in der aktuell ausgewählten Ansicht bereitgestellt. Sie werden ausgehend von der obersten Ebene der Ansichtshierarchie und dann nach unten gesendet, bis sie das entsprechende Ziel erreichen. Wenn Ihre View (oder ein untergeordnetes Element Ihrer Datenansicht) derzeit im Fokus ist, können Sie die Übertragung des Ereignisses mit der dispatchKeyEvent()-Methode sehen. Anstatt Schlüsselereignisse über Ihre Ansicht zu erfassen, können Sie auch alle Ereignisse in Ihrer Aktivität mit onKeyDown() und onKeyUp() empfangen.

Denken Sie bei der Texteingabe für Ihre Anwendung auch daran, dass viele Geräte ausschließlich Software-Eingabemethoden haben. Diese Methoden müssen nicht schlüsselbasiert sein. Einige können Spracheingaben, Handschriften usw. verwenden. Selbst wenn eine Eingabemethode eine tastaturähnliche Oberfläche bietet, löst sie im Allgemeinen nicht die Ereignisfamilie onKeyDown() aus. Sie sollten niemals eine UI erstellen, für die bestimmte Tastenbetätigungen gesteuert werden müssen, es sei denn, Sie möchten Ihre Anwendung auf Geräte mit einer Hardwaretastatur beschränken. Verlassen Sie sich insbesondere nicht auf diese Methoden, um die Eingabe zu validieren, wenn der Nutzer die Eingabetaste drückt. Verwenden Sie stattdessen Aktionen wie IME_ACTION_DONE, um der Eingabemethode zu signalisieren, wie Ihre Anwendung reagiert, sodass die Benutzeroberfläche sinnvoll geändert werden kann. Vermeiden Sie Annahmen darüber, wie eine Softwareeingabemethode funktionieren sollte, und vertrauen Sie ihr einfach darauf, Ihrer Anwendung bereits formatierten Text bereitzustellen.

Hinweis:Android ruft zuerst Event-Handler und dann die entsprechenden Standard-Handler aus der Klassendefinition auf. Daher wird durch die Rückgabe von true von diesen Event-Listenern die Weitergabe des Ereignisses an andere Event-Listener gestoppt und auch der Callback an den Standard-Event-Handler in der Ansicht blockiert. Wenn Sie true zurückgeben, sollten Sie also sicher sein, dass Sie das Ereignis beenden möchten.

Event-Handler

Wenn Sie eine benutzerdefinierte Komponente aus View erstellen, können Sie mehrere Callback-Methoden definieren, die als Standard-Event-Handler verwendet werden. Im Dokument über benutzerdefinierte Ansichtskomponenten finden Sie Informationen zu einigen häufigen Callbacks, die für die Ereignisverarbeitung verwendet werden. Dazu gehören:

Es gibt einige andere Methoden, die Sie kennen sollten. Sie gehören nicht zur View-Klasse, können sich aber direkt auf die Verarbeitung von Ereignissen auswirken. Berücksichtigen Sie bei der Verwaltung komplexerer Ereignisse innerhalb eines Layouts diese anderen Methoden:

Touch-Modus

Wenn ein Nutzer eine Benutzeroberfläche mit Richtungstasten oder einem Trackball verwendet, ist es erforderlich, Aktionen wie Schaltflächen hervorzuheben, damit der Nutzer sehen kann, was Eingaben akzeptiert. Wenn das Gerät jedoch über Touchfunktionen verfügt und der Nutzer durch Berühren mit der Benutzeroberfläche interagiert, ist es nicht mehr erforderlich, Elemente hervorzuheben oder eine bestimmte Ansicht hervorzuheben. Daher gibt es einen Interaktionsmodus namens „Touch-Modus“.

Bei einem berührungsfähigen Gerät wechselt der Nutzer in den Touchmodus, sobald der Nutzer den Bildschirm berührt. Ab diesem Zeitpunkt sind nur noch Ansichten fokussierbar, bei denen isFocusableInTouchMode() „true“ ist, z. B. Textbearbeitungs-Widgets. Andere Ansichten, die angetippt werden können, wie etwa Schaltflächen, werden nicht hervorgehoben, wenn sie berührt werden. Sie lösen einfach ihre Zuhörer aus, wenn sie gedrückt werden.

Jedes Mal, wenn ein Nutzer auf eine Richtungstaste drückt oder mit einem Trackball scrollt, beendet das Gerät den Touchmodus und sucht nach einer Ansicht, die im Fokus ist. Jetzt können Nutzende die Interaktion mit der Benutzeroberfläche fortsetzen, ohne den Bildschirm zu berühren.

Der Touch-Modus wird im gesamten System (alle Fenster und Aktivitäten) beibehalten. Wenn du den aktuellen Status abfragen möchtest, kannst du isInTouchMode() aufrufen, um zu sehen, ob sich das Gerät derzeit im Touchmodus befindet.

Fokus auf Handhabung

Das Framework übernimmt die routinemäßige Fokusbewegung als Reaktion auf die Eingabe der Nutzenden. Dies beinhaltet das Ändern des Fokus beim Entfernen oder Ausblenden von Ansichten oder wenn neue Ansichten verfügbar werden. Die Aufrufe signalisieren, dass sie bereit sind, sich auf die isFocusable()-Methode zu konzentrieren. Wenn Sie ändern möchten, ob eine Ansicht den Fokus fokussieren kann, rufen Sie setFocusable() auf. Im Touchmodus können Sie mit isFocusableInTouchMode() abfragen, ob eine Ansicht den Fokus zulässt. Sie können dies mit setFocusableInTouchMode() ändern.

Auf Geräten mit Android 9 (API-Level 28) oder höher wird bei Aktivitäten kein Schwerpunkt zugewiesen. Stattdessen müssen Sie bei Bedarf den anfänglichen Fokus explizit anfordern.

Die Fokusbewegung basiert auf einem Algorithmus, der den nächsten Nachbarn in einer bestimmten Richtung findet. In seltenen Fällen kann es vorkommen, dass der Standardalgorithmus nicht dem gewünschten Verhalten des Entwicklers entspricht. In diesen Fällen können Sie explizite Überschreibungen mit den folgenden XML-Attributen in der Layoutdatei festlegen: nextFocusDown, nextFocusLeft, nextFocusRight und nextFocusUp. Fügen Sie der Datenansicht von aus, auf der der Fokus verlassen wird, eines dieser Attribute hinzu. Legen Sie als Wert des Attributs die ID der Ansicht auf fest, auf die der Fokus liegen soll. Beispiel:

<LinearLayout
    android:orientation="vertical"
    ... >
  <Button android:id="@+id/top"
          android:nextFocusUp="@+id/bottom"
          ... />
  <Button android:id="@+id/bottom"
          android:nextFocusDown="@+id/top"
          ... />
</LinearLayout>

Normalerweise würde die Navigation von der ersten Schaltfläche bei diesem vertikalen Layout nirgendwohin gehen – ebenso wenig wie von der zweiten Schaltfläche aus nach unten. Nachdem nun die obere Schaltfläche die untere als nextFocusUp definiert hat (und umgekehrt), wird der Navigationsfokus von oben nach unten und von unten nach oben verschoben.

Wenn Sie eine Ansicht in Ihrer UI als fokussierbar deklarieren möchten (was normalerweise nicht der Fall ist), fügen Sie der Ansicht in Ihrer Layout-Deklaration das XML-Attribut android:focusable hinzu. Legen Sie den Wert true fest. Sie können eine Ansicht auch im Touchmodus mit android:focusableInTouchMode als fokussierbar deklarieren.

Wenn Sie eine bestimmte Ansicht anfordern möchten, um den Fokus zu erhalten, rufen Sie requestFocus() auf.

Verwenden Sie onFocusChange(), wie im Abschnitt Ereignis-Listener beschrieben, um auf Fokusereignisse zu warten und sich benachrichtigen zu lassen, wenn eine Ansicht den Fokus aufnimmt oder verliert.