Android onClick in XML vs. OnClickListener

84

Mir ist klar, dass zuvor eine ähnlich formulierte Frage gestellt wurde, aber das ist anders. Ich bin ziemlich neu in der Entwicklung von Android-Apps und habe drei Fragen zu den Unterschieden zwischen dem android:onclick=""XML-Attribut und der setOnClickListenerMethode.

  1. Was sind die Unterschiede zwischen den beiden? Liegt der Unterschied zwischen den beiden Implementierungen zur Kompilierungs- oder Laufzeit oder bei beiden?

  2. Welche Anwendungsfälle sind für welche Implementierung günstig?

  3. Welchen Unterschied macht die Verwendung von Fragmenten in Android bei der Auswahl der Implementierung?

KG6ZVP
quelle
1
Für # 2: Sie sollten vorsichtig sein, wenn Sie die XML verwenden, onclickda Sie sicherstellen müssen, dass jede Klasse diese Methode implementiert. Dies setzt voraus, dass Sie das Layout mehrmals verwenden. Wenn Sie jedoch eine Java-Schnittstelle hätten, um sicherzustellen, dass die Methode in allen Klassen vorhanden ist, die sie implementiert haben, müssen Sie sich keine Sorgen machen.
Uxonith
Wäre eine Java-Oberfläche, wie Sie sie beschrieben haben, nicht so gut wie das Erweitern oder Implementieren von OnClickListener?
KG6ZVP
Ich habe das schon einmal untersucht und ich denke, es steckt ein bisschen mehr dahinter als die Präferenz, aber es tut mir leid, dass ich nicht mehr viel sagen kann, da es eine Weile her ist. Ich mag das, android:onclickwenn es bequem ist, aber ich weiß, dass es manchmal Probleme verursacht hat, und ich kann mich auch nicht daran erinnern :)
Uxonith
xml onClick funktioniert nicht für verschachtelte Layoutelemente, die in API Level 19
Amit Kaushik
1
Ich habe selten Code von anderen Leuten gesehen, die Android: onClick implementieren, und es ist am verwirrendsten, wenn Sie anderen Code durchsehen. Da es nicht alle Möglichkeiten von setOnClickListener gibt, verwendet meiner Meinung nach fast jeder nur setOnClickListener
Christian

Antworten:

121

Unterschied zwischen OnClickListener und OnClick:

  • OnClickListener ist die Schnittstelle, die Sie implementieren müssen, und kann auf eine Ansicht in Java-Code festgelegt werden.
  • OnClickListener wartet darauf, dass jemand tatsächlich klickt. Onclick bestimmt, was passiert, wenn jemand klickt.
  • In letzter Zeit hat Android den Ansichten android: onclick ein XML-Attribut hinzugefügt, mit dem Klicks direkt in der Aktivität der Ansicht verarbeitet werden können, ohne dass eine Schnittstelle implementiert werden muss.
  • Sie können bei Bedarf problemlos eine Listener-Implementierung gegen eine andere austauschen.
  • Mit einem OnClickListener können Sie die Aktion / das Verhalten des Klickereignisses von der Ansicht trennen, die das Ereignis auslöst. Während dies für einfache Fälle keine so große Sache ist, könnte dies für die komplexe Ereignisbehandlung eine bessere Lesbarkeit und Wartbarkeit des Codes bedeuten
  • Da OnClickListener eine Schnittstelle ist, kann die Klasse, die sie implementiert, flexibel die Instanzvariablen und -methoden bestimmen, die zur Behandlung des Ereignisses erforderlich sind. Auch dies ist in einfachen Fällen keine große Sache, aber in komplexen Fällen möchten wir die Variablen / Methoden, die sich auf die Ereignisbehandlung beziehen, nicht unbedingt mit dem Code der Ansicht verwechseln, der das Ereignis auslöst.
  • Der onClick mit Funktionsbindung im XML-Layout ist eine Bindung zwischen onClick und der Funktion, die aufgerufen wird. Die Funktion muss ein Argument (die Ansicht) haben, damit onClick funktioniert.

Beide funktionieren auf die gleiche Weise, nur dass einer über Java-Code und der andere über XML-Code festgelegt wird.

Implementierung des setOnClickListener-Codes:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

XML-Implementierung:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

Performance:

Beide sind in der Leistung gleich. XML wird beim Kompilieren in Binärcode vorab analysiert. Es gibt also keinen Overhead in Xml.

Einschränkung:

android: onClick ist ab API-Level 4 verfügbar. Wenn Sie also auf <1,6 abzielen, können Sie es nicht verwenden.

Jebasuthan
quelle
`XML wird beim Kompilieren in Binärcode vorab analysiert` Was bedeutet diese Anweisung genau? Da ich den Dexcode eines apk gesehen habe, dessen Manifest-Datei android: onClick enthält, habe ich keinen Code gefunden, der den Listener
VicX
tolle Erklärung. +1
Zia Ur Rahman
1
Tatsächlich gibt es in XML einen gewissen Overhead . Wenn Sie zum ersten Mal auf die Schaltfläche klicken, wird durch Reflektion die Methode festgelegt, die aufgerufen werden soll . Dies ist jedoch für die meisten Anwendungsfälle wahrscheinlich vernachlässigbar (und vorzeitige Optimierung ist die Wurzel allen Übels).
Yoel
Kann ich sowohl android: onClick als auch setOnClickListener verwenden, um gleichzeitig verschiedene Aufgaben zu erledigen?
Taufik Nur Rahmanda
20

Ich bin schockiert, dass niemand darüber gesprochen hat, aber seien Sie vorsichtig, obwohl android:onClickXML eine bequeme Möglichkeit zu sein scheint, mit Klicks umzugehen, macht die setOnClickListenerImplementierung etwas Zusätzliches als das Hinzufügen von onClickListener. In der Tat hat es die Eigenschaft view clickableauf true gesetzt.

Während dies bei den meisten Android-Implementierungen möglicherweise kein Problem darstellt, ist die Schaltfläche laut Telefonkonstruktor standardmäßig immer klickbar = wahr, während andere Konstruktoren in einigen Telefonmodellen in Nicht-Schaltflächenansichten möglicherweise standardmäßig klickbar = falsch sind.

Das Festlegen des XML-Dokuments reicht also nicht aus. Sie müssen die ganze Zeit darüber nachdenken, eine android:clickable="true"Nicht-Schaltfläche hinzuzufügen. Wenn Sie ein Gerät haben, auf dem die Standardeinstellung anklickbar ist = true, und Sie einmal vergessen, dieses XML-Attribut einzufügen, werden Sie es nicht bemerken Das Problem zur Laufzeit wird aber das Feedback auf den Markt bekommen, wenn es in den Händen Ihrer Kunden liegt!

Darüber hinaus können wir nie sicher sein, wie Proguard XML-Attribute und Klassenmethoden verschleiern und umbenennen wird, sodass wir nicht 100% sicher sind, dass sie eines Tages niemals einen Fehler haben werden.

Wenn Sie also nie Probleme haben und nie darüber nachdenken möchten, ist es besser, setOnClickListenerBibliotheken wie ButterKnife mit Anmerkungen zu verwenden@OnClick(R.id.button)

Livio
quelle
1
Haben Sie Erfahrung (oder irgendwo gesehen), dass ein Fehler aufgrund von Verschleierung bei der Verwendung aufgetreten ist android:onClick?
Akram
Danke mein Herr! Ihre Antwort ist sehr hilfreich!
Yi Shen
11

Einfach:

Wenn Sie android:onClick = "someMethod" in XML haben , sucht es public void someMethodin Ihrer Aktivitätsklasse nach. OnClickListenerwird direkt von Ihrer Aktivität aufgerufen und ist mit einer bestimmten verknüpft View. Zum Beispiel someButton.setOnClickListenerund im folgenden Code wird gesagt, was zu tun ist, wenn someButtongedrückt wird.

Ich hoffe es hilft :)

Marson
quelle
3

Wie bereits erwähnt: Beide sind eine Möglichkeit, als Reaktion auf ein Ereignis, in diesem Fall ein Klickereignis, Logik hinzuzufügen.

Ich würde eine Trennung zwischen Logik und Präsentation anstreben, genau wie wir es in der HTML / JavaScript-Welt tun: Lassen Sie das XML für die Präsentation und fügen Sie Ereignis-Listener mithilfe von Code hinzu.

Stephan van Hoof
quelle
Einverstanden, es sei denn, es handelt sich um eine sehr kleine App mit einem einfachen Verhalten, sollte Ihr
gesamter
0

Wenn Sie mehrere Schaltflächen mit nur einer Methode haben, empfehle ich, dies in Java zu tun. Wenn Sie jedoch eine Schaltfläche mit einer bestimmten Methode haben, ist onClick in XML besser.

Megs
quelle
0

Es ist bequemer, immer das Attribut android: onClick zu verwenden, es sei denn, Sie haben einen guten Grund, dies nicht zu tun, wenn Sie beispielsweise die Schaltfläche zur Laufzeit instanziieren oder das Klickverhalten in einer Fragment-Unterklasse deklarieren müssen.

Mustapha Hadid
quelle
3
Ich habe selten Code von anderen Leuten gesehen, die Android: onClick implementieren, und es ist am verwirrendsten, wenn Sie anderen Code durchsehen. Da es nicht alle Möglichkeiten von setOnClickListener gibt, verwendet meiner Meinung nach fast jeder nur setOnClickListener
Christian
0

Es gibt mehrere Gründe, warum Sie eine programmgesteuert festlegen möchten OnClickListener. Das erste ist, wenn Sie jemals das Verhalten Ihrer Schaltfläche ändern möchten, während Ihre App ausgeführt wird. Sie können Ihre Schaltfläche ganz auf eine andere Methode richten oder die Schaltfläche einfach deaktivieren, indem Sie eine festlegenOnClickListener festlegen, die nichts bewirkt.

Wenn Sie einen Listener mit dem definieren onClick Attributs definieren, sucht die Ansicht nur in ihrer Hostaktivität nach einer Methode mit diesem Namen. Durch programmgesteuertes Festlegen von OnClickListenerkönnen Sie das Verhalten einer Schaltfläche von einem anderen Ort als der Hostaktivität aus steuern. Dies wird sehr relevant, wenn wir FragmentsMini-Aktivitäten verwenden, mit denen Sie wiederverwendbare Sammlungen von Ansichten mit einem eigenen Lebenszyklus erstellen können, die dann zu Aktivitäten zusammengestellt werden können. Fragmente müssen immer OnClickListenerszur Steuerung ihrer Schaltflächen verwendet werden, da sie keine Aktivitäten sind und nicht nach in onClick definierten Listenern durchsucht werden.

Rohan Vachhani
quelle
-2

Ich denke, der Hauptunterschied zwischen ihnen ist:

OnClick: Wenn Sie mit dem Finger auf die Schaltfläche klicken.

OnClickListner: Es kann eine größere Auswahl sein, die in verschiedenen Codes implementiert wird.

Wenn Sie beispielsweise die URL "ymail.com" eingeben, findet Yahoo Ihren Benutzernamen und Ihr Passwort in Ihrem Browser und aktiviert die Schaltfläche "Status klicken", um Ihre E-Mail zu öffnen. Diese Aktion sollte nur in onClickListener implementiert werden.

Das ist meine Idee!

Seyyed Mahmood Ahmadi
quelle
Das ist interessant, aber es gibt noch viel mehr. Ihr sollte eher ein Kommentar sein.
Dakatine