Jaki jest właściwy sposób implementacji interfejsu OnClickListener dla wielu przycisków


10

Moja aktywność na Androida zawiera wiele przycisków, z których wszystkie wymagają OnClickListener. Widziałem wiele różnych sposobów robienia tego, takich jak:

  • Implementacja interfejsu w klasie aktywności
  • Tworzenie oddzielnej klasy, która implementuje interfejs
  • Definiowanie anonimowej klasy wewnętrznej dla każdego przycisku.

Widziałem wiele przykładów każdego podejścia. Jednak nie jest dla mnie jasne, dlaczego jedno podejście byłoby stosowane zamiast drugiego. Czy różnice między tymi podejściami są stylistyczne, czy istnieją powody, które sprawiają, że jedno podejście jest lepsze?

Odpowiedzi:


6

Podobnie jak w przypadku wielu rzeczy, prawidłowe podejście zależy od tego, co próbujesz zrobić dla określonego przycisku i co jeszcze robisz z działaniem.

Klasa aktywności implementuje interfejs :
Jest to dobra opcja, gdy masz tylko jeden typ zadania do wykonania po wywołaniu tego detektora. Przykładem może być prosta forma z wieloma polami i przyciskiem Zapisz. Wolę, aby mój detektor zdarzeń nie sprawdzał źródła zdarzenia, aby zdecydować, co faktycznie należy zrobić. Wiem, że niektórzy mogą powiedzieć, że jest to kwestia stylu, ale wierzę, że nie wymaganie od słuchacza wykonania tej kontroli ułatwia śledzenie kodu, ponieważ będziesz wiedział dokładnie, co jest wywoływane dla każdego zdarzenia.

Inna klasa implementuje interfejs :
jak powiedziałem wyżej, wolę tę opcję, gdy mam wiele przedmiotów, które mogą wywołać to samo zdarzenie. Rozszerzając powyższy przykład, dodajmy czysty przycisk, który również wymaga detektora kliknięć. Utwórz jeden detektor, który wykona akcje zapisywania i ten, który wykona akcje usuwania. Każdy detektor jest dodawany tylko do komponentów, które spowodują tę akcję.

Ta implementacja ma dodatkową korzyść, z której możesz skorzystać, jeśli ci zależy. Zaletą jest to, że zapobiega wyzwalaniu przez inne klasy zdarzenia wewnątrz twojej klasy aktywności. Ponieważ metoda interfejsu musi być publiczna, każdy, kto ma odwołanie do klasy, może uruchomić zdarzenie. Jeśli chcesz mieć precyzyjną kontrolę nad tym, kto może robić to, co w aplikacji, osobna klasa zapobiega, by ktokolwiek z odniesieniem do działania wyzwalał twoją formę do wyczyszczenia lub zapisania (lub potencjalnie złamał kod, jeśli słuchacz korzysta ze źródła, ale robi to nie obsługuje złych danych wejściowych).

Anonimowa klasa wewnętrzna implementuje interfejs :
To naprawdę tylko konkretny sposób na zbudowanie drugiej opcji użycia innej klasy jako implementacji. Ta opcja może jeszcze bardziej ograniczyć, kto ma dostęp do wyzwalania zdarzenia, ponieważ nikt inny nie może utworzyć wystąpienia klasy. Myślę jednak, że ważniejszym czynnikiem między tymi dwiema opcjami jest ilość pracy. Wyczyszczenie kilku pól tekstowych jest prostą i bezpośrednią operacją. Jednak proces zapisywania dla może wiązać się z wieloma zadaniami, jeśli sprawdzasz poprawność danych wejściowych (co powinieneś zrobić), piszesz do bazy danych w celu przechowywania wartości i uruchamiasz pewne działania po zapisaniu. W takim przypadku utworzenie oddzielnej klasy z własnym plikiem zapewni wyraźniejszy podział między formularzem wejściowym a przetwarzaniem danych. To z kolei zachowuje kod formularza zamiast większego pliku z zagnieżdżonymi wieloma klasami wewnętrznymi.


Wow, dzięki za odpowiedź. Jeśli chodzi o koszty ogólne, czy tworzenie wielu klas słuchaczy jest bardziej kosztowne?
slayton

@slayton: Zawsze będą koszty bez względu na to, co robisz. Pytanie powinno brzmieć „Czy różnica ma dla ciebie znaczenie?” Tworzenie większej liczby obiektów ma znaczenie, ale czas wykonania będzie dłuższy, jeśli słuchacz będzie musiał przejrzeć listę źródeł, aby zdecydować, co właściwie zrobić. Jeśli wykorzystanie pamięci i wydajność są dla Ciebie ważne, powinieneś profilować kod i decydować, co jest najlepsze w oparciu o twoje wymagania. Wątpiłbym jednak, aby był to szyjka butelki twojego kodu. Dopóki nie zostanie przedstawione inaczej, podejmuj decyzje, aby kod był bardziej przejrzysty i lepiej zorganizowany.
unholysampler

3

Czwarty sposób to ustawienie atrybutu onClick w układzie:

<Button android:onClick="clickHandlerForButtonX" />

który ma tę odpowiednią metodę w działaniu:

public void clickHandlerForButtonX(View v) {
    //Handle Button X here
}

ciekawe, nie wiedziałem, że możesz to zrobić. Chociaż wydaje się, że jest to specyficzny dla Androida mechanizm radzenia sobie z kliknięciami przycisków.
slayton

Zazwyczaj jednak używam „interfejsu klasy implementacji interfejsu” - w ten sposób wszystkie rzeczy związane z kliknięciami znajdują się w tym samym miejscu.
orjan

ta konkretna metoda nie działa z fragmentami.
Rahul Tiwari
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.