Frage zu OnClickListener. Verständnisproblem

mrkennedie89

Mitglied
Hallo,

ich bin gerade dabei mich etwas in die Materie der App-Entwicklung mit Android Studio und Java einzuarbeiten. Leider bereitet mir ein kleiner Codeschnipsel
schon Sorgen, da ich nicht wirklich durchsteige warum es so funktioniert. Es geht um folgendes Beispiel, bei dem mit OnClick der Zustand eines Buttons
verändert werden soll:

Java:
protected void onCreate(Bundle savedInstanceState) {
    ...
 
     View.OnClickListener onButtonClickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
               ...
        }
    };
 
   
    Button button = (Button) findViewById(R.id.button_activity_main);
 
    // Registrieren der OnClickListener-Instanz für den Button
    button.setOnClickListener(onButtonClickListener);
 
    ...
}

Soweit habe ich folgendes Verstanden: Es gibt eine Superklasse View in der das Interface OnClickListener angelegt ist mit der
nicht implementierten Methode onClick();
Um Code-Zeilen zu sparen wird OnClickListener on the fly im Programmablauf als anonyme Klasse eingebunden und die
Methode onClick direkt implementiert.
Das Buttonobjekt wird mit Hilfe der findViewbyID() Methode aufgerufen, weil die ID in der Klasse R gespeichert ist. So weiß die Activity Java
um welches Objekt aus der View es sich handelt.

Nun zur letzten Zeile: Warum wird das erzeugte Objekt von der Anyonymen Klasse OnClicklistener als Übergabeparameter
der Methode setOnClickListener übergben? Ist im Objekt onButtonClickListener die Methode onClick gespeichert?
Wie kann ich den gedanklichen Strich vom Button ziehen? Soweit ich weiß ist ein Button ja eine Unterklasse von TextView und
TextView wiederum von View?

Ich wäre für Hilfe dankbar.
 
Soweit hast Du das schon alles richtig verstanden (die Geschichte mit findViewById() ist etwas seltsam geschrieben, aber das sind jetzt Details, die an der Stelle nicht wirklich interessieren).

Es gibt also ein Interface View.OnClickListener. Dein onButtonClickListener ist eine Variable, die eine Referenz auf ein Objekt hält, das dieses Interface implementiert.

Jetzt zur Frage:
Warum wird das erzeugte Objekt von der Anyonymen Klasse OnClicklistener als Übergabeparameter
der Methode setOnClickListener übergben?
Weil ansonsten niemand weiß, was passieren soll, wenn auf die View geklickt wird.

Ist im Objekt onButtonClickListener die Methode onClick gespeichert?
Die Methode ist in der anonymen Klasse definiert, von der das Objekt (auf das onButtonClickListener verweist) eine Instanz ist.

Nachtrag:
Wie kann ich den gedanklichen Strich vom Button ziehen? Soweit ich weiß ist ein Button ja eine Unterklasse von TextView und
TextView wiederum von View?
Richtig, das siehst Du auch, wenn Du die Dokumentation aufschlägst. Button ist Subklasse von TextView, TextView ist Subklasse von View und View ist Subklasse von Object (wie alle Klassen).
 
Soweit hast Du das schon alles richtig verstanden (die Geschichte mit findViewById() ist etwas seltsam geschrieben, aber das sind jetzt Details, die an der Stelle nicht wirklich interessieren).

Es gibt also ein Interface View.OnClickListener. Dein onButtonClickListener ist eine Variable, die eine Referenz auf ein Objekt hält, das dieses Interface implementiert.

Jetzt zur Frage:

Weil ansonsten niemand weiß, was passieren soll, wenn auf die View geklickt wird.


Die Methode ist in der anonymen Klasse definiert, von der das Objekt (auf das onButtonClickListener verweist) eine Instanz ist.

Nachtrag:

Richtig, das siehst Du auch, wenn Du die Dokumentation aufschlägst. Button ist Subklasse von TextView, TextView ist Subklasse von View und View ist Subklasse von Object (wie alle Klassen).
Hi, danke für die Antwort. Ich verstehe aber immer noch nicht ganz was set.OnClickListener genau tut, abgesehen davon, dass er dem Button den Listener zur Verfügung stellt und, wenn er gedrückt wird, die Vorgaben des Interfaces im Programm durchlaufen lässt.
Was ich nicht verstehe ist das Prinzip dahinter. Ich habe bisher nur in Java die Grundlagen erlernt.

Wie kann ich mich diesem Prinzip nähern, dass ich es bspw. in Javacode nachbauen kann? Bzw. was sollte ich mir an Themen anschauen evtl. auch in anderen Sprachen um es vollständig erfassen zu können? Mir bereitet es irgendwie große Sorgen, wenn ich den Code einfach nur auswendig lerne aber nicht wirklich verstehe was dort in Android Studio passiert. Leider finde ich auch keine genauen Erklärungen.
 
Im Guide von Android steht zur Methode setOnClickListener "Register a callback to be invoked when this view is clicked.".
Was genau bedeutet der Callback hier?
 
Android (und viele andere GUI-Frameworks) sind Ereignisgesteuert. Das ist auf den ersten Blick etwas anders, als ein normaler Programmablauf. Wenn wir mal ein simples Java Programm ansehen

Java:
public void main(String args[]) {
macheWas();
macheNochWas();
}
Dann wird das der Reihe nach ausgeführt. Erst der Code aus macheWas() und dann der Code aus macheNochWas().

Alles sequentiel hintereinander.

Das ist für eine GUI natürlich blöd. Den da gibt es ja nicht einen Ablauf. Der hängt ganz stark davon ab, wie der Benutzer mit der GUI interagiert. Klick auf den einen Button, soll vielleicht X passieren. Klickt er auf einen anderen Button soll y passieren.

Das heißt, du kannst nicht einfach ein Programm schreiben, was von oben nach unten abgearbeitet wird. Stattdessen muss du definieren, was passieren soll, wenn gewisse Ereignisse eintreten. Das heißt, du definierst "Wenn der User auf den Button clickt soll das und das passieren". Und genau das ist der ClickListener. Das heißt, du sagst, wenn der Benutzer auf den Button clickt, soll folgende Funktion aufgerufen werden. Diese Funktion nennt sich Callback. Weil du rufst die Funktion nicht auf, sondern sagst (hier Android) wenn das Ereignis "User hat auf Button geklickt" auftritt, dann rufe mich an dieser Funktion zurück.

Klarer geworden?



Technisch ist das so, dass irgendwo von Android gesteuert folgenden Code gibt (In Wirklichkeit deutlich kompexer):

Java:
while (!benutzerHatAnwendungBeendet) {
  if (benutzerHatIrgendwoGeklikct()) {
    KlickbaresObjekt myObject = findeGeklicktesObjekt();
    if (myObject.hasClickListener()) {
      myObject.getClicklistener().fireEvent();
    }
  }
}
 
Callback Rückruf von System.

Du Teilst dem System Android mit welche Methode Code es ausführen soll wenn das System einen Klick erkennt.

Ein listener ist eine callback Methode.
 

Zurück
Oben