Event-Handling in Android

Android-Entwicklung: Benutzeroberfläche Logo
Was versteht man unter Event-Handling?

Allgemein hat jede Software eine grafische Benutzeroberfläche mit verschiedenen Steuerelementen, wie z. B. Buttons, die ein Anwender bedienen kann. Wenn ein Benutzer nun auf ein solches Steuerelement klickt, wird ein bestimmtes Ereignis (z. B. Klick-Ereignis) ausgelöst, welches entsprechend behandelt werden muss.

Diese Behandlung von Ereignissen wird in der Software-Entwicklung auch „Event-Handling“ genannt und basiert auf dem Konzept der ereignisorientierten Programmierung. Damit ist gemeint, dass der Programmablauf nicht linear verläuft, sondern sich an bestimmten Ereignissen orientiert. Tritt ein Ereignis ein, werden im Hintergrund mehrere Schritte abgearbeitet. Wie diese Schritte in Android aussehen, werden wir in diesem Blog-Artikel beschreiben.

 

Beispiel:

Im Screenshot unten siehst du beispielhaft die Kontakte-App von Android, bei der du über den „Plus„-Button (linkes Bild) eine neue Seite öffnest, um einen neuen Kontakt hinzufügen zu können (rechtes Bild). Sobald ein Benutzer auf das „Plus“ tippt, wird ein Klick-Ereignis ausgelöst und um dieses Event nun zu einem Erfolg zu führen (die Seite erfolgreich zu öffnen), benötigst du die Ereignisbehandlung, welche sich um die weitere Verarbeitung des Ereignisses im Hintergrund kümmert.

Android-Entwicklung: Event-Handling (Beispiel)

 

Wie funktioniert das Event-Handling?

Die Ereignisbehandlung besteht im Wesentlichen aus mehreren Schritten, die wir im weiteren Verlauf kurz vorstellen. Den Ablauf der Ereignisbehandlung zeigt das nachfolgende Schaubild, wobei die einzelnen Schritte unterhalb des Bildes erklärt werden.

Android-Entwicklung: Event-Handling (Ablauf)

 

1) Benutzer-Aktion:
Bevor das Event-Handling überhaupt zum Einsatz kommt, muss natürlich erstmal ein Ereignis durch eine Aktion des Benutzers auf der App-Oberfläche ausgelöst werden.

Beispiel:
Als Aktion ist im Grunde jede Interaktion des Benutzers mit der Bildschirm-Oberfläche (Touch-Screen) oder der Hardware-Tastatur gemeint, also z. B. das Drücken eines Buttons über eine virtuelle oder physische Taste:

Android-Entwicklung: Event-Handling (Klick-Event)
2) Event: 
Sobald der Benutzer mit einem UI-Element (z. B. Button) auf der Geräte-Oberfläche interagiert, wird ein Event (z. B. Klick-Ereignis) ausgelöst. Ereignisse werden dabei in Android in einer Warteschlange (Queue) gespeichert und nach dem FIFO-Prinzip (First-In, First-Out) abgearbeitet, d. h. diejenigen Ereignisse, die zuerst in der Warteschlange abgelegt werden, werden auch zuerst wieder entnommen und weiterverarbeitet.

Android-Entwicklung: Event-Handling (Warteschlange - Queue)
Das Android-Framework kann beispielsweise auf folgende Ereignisse reagieren:

-> Click-Event: Wird ausgelöst, wenn der Benutzer nur kurz auf ein Element tippt oder klickt 
-> Long-Click-Event: Wird ausgelöst, wenn der Benutzer länger auf ein Element tippt oder klickt 
-> Touch-Event: Wird ausgelöst, wenn der Benutzer den Bildschirm in irgendeiner Form berührt
3) Event-Listener:
Um ein vom Benutzer ausgelöstes Ereignis behandeln zu können, muss zuerst ein Event-Listener bei einem UI-Element registriert werden. Ein solcher Listener ist für den Empfang eines Ereignisses zuständig und informiert den Event-Handler über das Eintreffen eines Events. Es gibt dabei mehrere Event-Listener innerhalb der View-Klasse, die für unterschiedliche Events eingesetzt und auf verschiedene Weisen registriert werden können. 

Unter anderem gibt es folgende Event-Listener im Android-Framework:

-> OnClickListener(): Wird beim Anklicken eines Steuerelements (z. B. Button) aufgerufen
-> OnLongClickListener(): Wird aufgerufen, wenn ein UI-Element angeklickt und gehalten wird
-> OnFocusChangeListener(): Wird aufgerufen, wenn sich der Fokuszustand eines UI-Elements geändert hat
-> OnTouchListener(): Wird aufgerufen, wenn ein UI-Element berührt wird


3a) Event-Listener-Registrierung:
Es gibt für die Registrierung eines Event-Listeners mehrere Möglichkeiten, wobei wir hier lediglich drei davon vorstellen:

(A) Das Event-Listener-Interface wird von der Activity-Klasse implementiert:
Bei der ersten Möglichkeit wird das Event-Listener-Interface über die Activity-Klasse implementiert. Dabei musst du hinter den Namen der Basis-Klasse für Activities, also "AppCompatActivity" oder "Activity", zuerst das Schlüsselwort "implements" und dahinter "View.OnXXXListener" schreiben, wobei die drei "XXX" für ein bestimmtes Ereignis stehen (z. B. "Click" für ein Klick-Ereignis). Hier musst du selbst entscheiden, für welches Ereignis du den Listener registrieren möchtest. In der "onCreate()"-Methode der Activity registrierst du anschließend den Event-Listener über die "setOnXXXListener()"-Methode bei einem Steuerelement (in unserem Fall einem Button). Auch hier stehen die drei "XXX" wieder stellvertretend für ein bestimmtes Ereignis. 

Beispiel:
//Bei der Klassendefinition wird ganz rechts "implements View.OnXXXListener" geschrieben
public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        Button myButton = (Button)findViewById(R.id.myButton);
        /* Der Listener wird über die Methode "setOnClickListener()" beim UI-Element "Button"
          für ein Klick-Ereignis registriert und mit "this" eine Referenz auf die Activity übergeben  
        */
        myButton.setOnClickListener(this);
    }

    // Hier wird später der Event-Handler implementiert
}


(B) Registrierung über eine anonyme innere Klasse: 
Bei dieser Möglichkeit implementierst du das Event-Listener-Interface nicht für die gesamte Activity-Klasse, sondern nur für ein einzelnes UI-Element. Dabei setzt du erneut die "setOnXXXListener()"-Methode für die Registrierung des Listeners ein und übergibst dieser Methode als Parameter eine per "new"-Operator dynamisch erstellte und anonyme Instanz des Event-Listeners. Diese Art der Registrierung hat den Vorteil, dass du problemlos über den Event-Handler auf die privaten Daten der Activity-Klasse zugreifen kannst.

Beispiel: 
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button myButton = (Button)findViewById(R.id.myButton);
        /* Der Listener wird auch hier über die "setOnXXXListener()"-Methode registriert, aber es
           wird diesmal keine Referenz auf die Activity übergeben, sondern eine anonyme
           Instanz des Listener-Interfaces 
        */
        myButton.setOnClickListener(new View.OnClickListener() {
           //Hier wird später der Event-Handler implementiert
        });
}


(C) Registrierung über die XML-Layout-Datei (Nur für Klick-Event): 
Diese Möglichkeit ist nur für ein "Klick-Ereignis" anwendbar, hat allerdings den Vorteil, dass etwas weniger Arbeit anfällt, da weder das Event-Listener-Interface noch die "setOnXXXListener"-Methode implementiert werden muss. Es muss nur das Attribut "onClick" zur XML-Layout-Datei hinzugefügt und der Name der Event-Handler-Methode zugewiesen werden.

Beispiel: 
Im Screenshot unten siehst du die "activity_main.xml"-Datei mit einem Button als UI-Element. Diesem Button wurde nun in der Zeile mit dem roten Pfeil das Attribut "onClick" hinzugefügt und der Name "meineEventHandlerMethode" des Event-Handlers zugewiesen.

Android-Entwicklung: Event-Handling (Event-Listener-Registrierung über XML
public class MainActivity extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 

        Button myButton = (Button)findViewById(R.id.myButton);    
        //Die Event-Listener-Registrierung beim Button ist hier unnötig
   }
    // Das hier ist die Event-Handler-Methode mit dem Namen "meineEventHandlerMethode"
    public void meineEventHandlerMethode(View v) {
        //Hier implementierst du, was der Event-Handler konkret tun soll
    }
}
4) Event-Handler:
Wenn durch den Benutzer ein Ereignis ausgelöst wurde und ein passender Event-Listener für das Ereignis registriert wurde, ruft dieser den Event-Handler auf, wobei es sich hier um eine Callback-Methode wie z. B. onClick() handelt, die das Ereignis behandelt. In Android werden mehrere Event-Handler unterschieden, die jeweils für ein anderes Ereignis zuständig sind:

-> onClick(): Wird aufgerufen, wenn ein UI-Element kurz angetippt oder angeklickt wird 
-> onLongClick(): Wird aufgerufen, wenn ein UI-Element angeklickt und gehalten wird 
-> onFocusChange(): Wird aufgerufen, wenn sich der Fokuszustand einer View geändert hat 
-> onTouch(): Wird aufgerufen, wenn ein UI-Element berührt wird

Info: Es gibt noch weitere Event-Handler-Methoden, auf die wir hier jedoch nicht weiter eingehen.

Beispiel: 
Bei dem nachfolgenden Beispiel-Code wird zunächst das Event-Listener-Interface von der Activity-Klasse implementiert und der Event-Listener beim Button "myButton" registriert. Anschließend erfolgt die Implementierung der Event-Handler-Methode "onClick", der ein View-Objekt (in unserem Fall der Button "myButton") übergeben wird.

public class MainActivity extends Activity implements View.OnClickListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_main); 
        Button myButton = (Button)findViewById(R.id.myButton); 
        //Registrierung des Event-Listeners beim UI-Element "myButton"
        myButton.setOnClickListener(this); 
    }

    //Event-Handler "onClick" zur Verarbeitung eines Klick-Events 
    @Override
    protected void onClick(View v) { 
    /* Hier legst du fest, was der Event-Handler tun soll. 
       Z. B. könntest du hier den Code zum Öffnen einer neuen Activity schreiben,
       wie das z. B. für den Plus-Button der Kontakte-App von Google im ersten Beispiel
       getan wurde */
    }
}