Android onClick w XML a OnClickListener

86

Zdaję sobie sprawę, że podobnie sformułowane pytanie zadawano już wcześniej, ale jest inaczej. Jestem całkiem nowy w tworzeniu aplikacji na Androida i mam trzy pytania dotyczące różnic między android:onclick=""atrybutem XML a setOnClickListenermetodą.

  1. Jakie są różnice między nimi? Czy jest różnica między dwiema implementacjami znalezionymi w czasie kompilacji lub w czasie wykonywania, czy też obydwoma?

  2. Jakie przypadki użycia są korzystne dla której implementacji?

  3. Jakie różnice powoduje użycie fragmentów w systemie Android przy wyborze implementacji?

KG6ZVP
źródło
1
Punkt 2: należy zachować ostrożność podczas korzystania z XML, onclickponieważ należy upewnić się, że każda klasa implementuje tę metodę. Zakłada się, że używasz układu więcej niż raz. Jeśli jednak miałbyś mieć interfejs Java, aby upewnić się, że metoda jest we wszystkich klasach, które ją zaimplementowały, nie musiałbyś się martwić.
Uxonith
Czy posiadanie interfejsu java, jak opisałeś, nie byłoby prawie tym samym, co rozszerzanie lub implementowanie OnClickListener?
KG6ZVP
Patrzyłem na to wcześniej i myślę, że jest w tym trochę więcej niż preferencje, ale przepraszam, że nie mogę powiedzieć nic więcej, ponieważ minęło trochę czasu. Podoba mi się, android:onclickkiedy jest to wygodne, ale wiem, że czasami powodowało to problemy, których też nie pamiętam :)
Uxonith
xml onClick nie działa dla zagnieżdżonych elementów układu, które są dynamicznie zawyżane na poziomie API 19
Amit Kaushik
1
Rzadko widziałem kod od innych osób implementujących android: onClick i jest to najbardziej zagmatwane, gdy przeglądasz kod kogoś innego. Ponieważ nie ma wszystkich możliwości setOnClickListener, prawie wszyscy używają tylko setOnClickListener moim zdaniem
Christian

Odpowiedzi:

122

Różnica między OnClickListener a OnClick:

  • OnClickListener to interfejs, który należy zaimplementować i można go ustawić na widok w kodzie java.
  • OnClickListener to to, co czeka, aż ktoś faktycznie kliknie, onclick określa, co się stanie, gdy ktoś kliknie.
  • Ostatnio Android dodał atrybut xml do widoków o nazwie android: onclick, który może być używany do obsługi kliknięć bezpośrednio w działaniu widoku bez konieczności implementowania żadnego interfejsu.
  • W razie potrzeby możesz łatwo zamienić jedną implementację odbiornika na inną.
  • OnClickListener umożliwia oddzielenie akcji / zachowania zdarzenia kliknięcia od widoku wyzwalającego zdarzenie. Podczas gdy w prostych przypadkach nie jest to taka wielka sprawa, w przypadku złożonej obsługi zdarzeń może to oznaczać lepszą czytelność i łatwość utrzymania kodu
  • Ponieważ OnClickListener jest interfejsem, klasa, która go implementuje, ma elastyczność w określaniu zmiennych instancji i metod potrzebnych do obsługi zdarzenia. Ponownie, nie jest to wielka sprawa w prostych przypadkach, ale w przypadku złożonych przypadków nie chcemy koniecznie mieszać zmiennych / metod związanych z obsługą zdarzenia z kodem widoku wyzwalającego zdarzenie.
  • OnClick z powiązaniem funkcji w układzie XML jest powiązaniem między onClick a funkcją, którą będzie wywoływać. Funkcja musi mieć jeden argument (Widok), aby onClick działał.

Obie działają w ten sam sposób, tylko jeden jest ustawiany za pomocą kodu java, a drugi przez kod xml.

Implementacja kodu setOnClickListener:

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
}

Implementacja XML:

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

Występ:

Oba są takie same pod względem wydajności. XML jest wstępnie analizowany do kodu binarnego podczas kompilacji. więc nie ma nad głową w Xml.

Ograniczenie:

android: onClick jest przeznaczony dla interfejsu API na poziomie 4, więc jeśli celujesz w <1,6, nie możesz go używać.

Jebasuthan
źródło
`XML jest wstępnie parsowany do kodu binarnego podczas kompilacji` Co dokładnie oznacza ta instrukcja? Ponieważ widziałem dexcode apk, który ma android: onClick w swoim pliku manifestu, ale nie znalazłem żadnego kodu, który wyraźnie
ustawiłby
niesamowite wyjaśnienie. +1
Zia Ur Rahman
1
Właściwie w XML jest trochę narzutu . Po pierwszym kliknięciu przycisku odbicie jest używane do określenia metody, która ma zostać wywołana . Jednak jest to prawdopodobnie nieistotne w większości przypadków użycia (a przedwczesna optymalizacja jest źródłem wszelkiego zła).
Yoel
21

Jestem zszokowany, że nikt o tym nie mówił, ale bądź ostrożny, chociaż android:onClickXML wydaje się być wygodnym sposobem obsługi kliknięć, setOnClickListenerimplementacja robi coś więcej niż dodanie onClickListener. Rzeczywiście, ustawia właściwość view clickablena true.

Chociaż może to nie stanowić problemu w większości implementacji Androida, według konstruktora telefonu, domyślnie przycisk button ma zawsze wartość clickable = true, ale inne konstruktory w niektórych modelach telefonu mogą mieć domyślną wartość clickable = false w widokach innych niż Button.

Więc ustawienie XML nie wystarczy, musisz cały czas myśleć, aby dodać android:clickable="true"brak przycisku, a jeśli masz urządzenie, w którym wartość domyślna jest klikalna = prawda i zapomnisz choć raz umieścić ten atrybut XML, nie zauważysz problem w czasie wykonywania, ale dostaniesz informację zwrotną na rynku, kiedy trafi on w ręce Twoich klientów!

Ponadto nigdy nie możemy być pewni, w jaki sposób program Proguard zaciemni i zmieni nazwy atrybutów XML i metody klas, więc nie jest w 100% bezpieczny, że pewnego dnia nigdy nie będzie miał błędu.

Jeśli więc nigdy nie chcesz mieć kłopotów i nigdy o tym nie myśl, lepiej skorzystać z setOnClickListenerbibliotek lub takich jak ButterKnife z adnotacją@OnClick(R.id.button)

Livio
źródło
1
Czy miałeś jakieś doświadczenie (lub gdzieś widziałeś), że błąd wystąpił z powodu zaciemnienia podczas używania android:onClick?
Akram
Dziękuję Panu! Twoja odpowiedź jest bardzo pomocna!
Yi Shen
12

Po prostu:

Jeśli masz android:onClick = "someMethod" w XML , szuka public void someMethodw klasie Activity. OnClickListenerjest wywoływana bezpośrednio z Twojej Aktywności i jest powiązana z jakimś konkretnym View. Na przykład someButton.setOnClickListenerw poniższym kodzie jest powiedziane, co należy zrobić po someButtonnaciśnięciu.

Mam nadzieję, że to pomoże :)

Marson
źródło
4

Jak powiedziałem wcześniej: oba są sposobem na dodanie logiki w odpowiedzi na zdarzenie, w tym przypadku zdarzenie typu „kliknięcie”.

Wybrałbym oddzielenie logiki od prezentacji, tak jak robimy to w świecie HTML / JavaScript: zostaw XML do prezentacji i dodaj detektory zdarzeń za pomocą kodu.

Stephan van Hoof
źródło
1
Zgoda, chyba że jest to bardzo mała aplikacja z prostym zachowaniem, cały wykonywany kod powinien być przechowywany oddzielnie i dobrze zorganizowany, najlepiej przy użyciu oddzielnych metod
OzzyTheGiant
0

Jeśli masz kilka przycisków wykorzystujących tylko jedną metodę, sugeruję zrobienie tego w java. Ale jeśli masz przycisk z jedną określoną metodą, onClick w XML byłby lepszy.

Megs
źródło
0

Wygodniej jest zawsze używać atrybutu android: onClick, chyba że masz dobry powód, aby tego nie robić, na przykład, jeśli tworzysz wystąpienie Button w czasie wykonywania lub musisz zadeklarować zachowanie kliknięcia w podklasie Fragment.

Mustapha Hadid
źródło
3
Rzadko widziałem kod od innych osób implementujących android: onClick i jest to najbardziej zagmatwane, gdy przeglądasz kod kogoś innego. Ponieważ nie ma wszystkich możliwości setOnClickListener, prawie wszyscy używają tylko setOnClickListener moim zdaniem
Christian
0

Istnieje kilka powodów, dla których warto programowo ustawić plik OnClickListener. Po pierwsze, jeśli kiedykolwiek zechcesz zmienić zachowanie przycisku, gdy aplikacja jest uruchomiona. Możesz skierować swój przycisk całkowicie na inną metodę lub po prostu wyłączyć przycisk, ustawiając opcję, OnClickListenerktóra nic nie robi.

Kiedy definiujesz detektor za pomocą onClickatrybutu, widok szuka metody o tej nazwie tylko w swoim działaniu hosta. Programowe ustawienie OnClickListenerpozwala kontrolować zachowanie przycisku z innego miejsca niż aktywność hosta. Stanie się to bardzo istotne, gdy użyjemy Fragments, które są w zasadzie mini działaniami, pozwalającymi na tworzenie kolekcji widoków wielokrotnego użytku z własnym cyklem życia, które można następnie połączyć w działania. Fragmentów zawsze trzeba używać OnClickListenersdo kontrolowania swoich przycisków, ponieważ nie są one działaniami i nie będą wyszukiwane w poszukiwaniu detektorów zdefiniowanych w onClick.

Rohan Vachhani
źródło
-2

Myślę, że główna różnica między nimi to:

OnClick: Po kliknięciu przycisku palcem.

OnClickListner: To może być szerszy wybór, który można zaimplementować w różnych kodach.

Na przykład, kiedy wpiszesz adres url „ymail.com”, yahoo znajdzie twoją nazwę użytkownika i hasło z przeglądarki i włączy przycisk stanu kliknięcia, aby otworzyć twoją pocztę. Ta akcja powinna być realizowana tylko w onClickListener.

To jest mój pomysł!

Seyyed Mahmood Ahmadi
źródło
To ciekawe, ale jest o wiele więcej; Twój powinien raczej być komentarzem.
Dakatine