Android onClick в XML проти OnClickListener


86

Я усвідомлюю, що подібне сформульоване питання вже задавали раніше, але це інше. Я досить новачок у розробці програм для Android, і у мене є три запитання щодо різниці між android:onclick=""атрибутом XML та setOnClickListenerметодом.

  1. Які відмінності між ними? Чи існує різниця між двома реалізаціями, виявленими під час компіляції чи часу виконання, або обома?

  2. Які випадки використання сприятливі для якої реалізації?

  3. Яку різницю використовує фрагменти в Android у виборі реалізації?


1
Для №2: Ви повинні бути обережними при використанні xml, onclickоскільки вам потрібно переконатися, що кожен клас реалізує цей метод. Це припускає, що ви використовуєте макет більше одного разу. Однак, якщо ви хочете мати інтерфейс Java, щоб переконатися, що метод знаходиться у всіх класах, які його реалізували, вам не доведеться турбуватися.
Uxonith

Чи не матиме інтерфейс Java, як ви описали, майже таким самим, як розширення або обмеження OnClickListener?
KG6ZVP

Я вже розглядав це раніше і думаю, що тут є трохи більше, ніж перевага, але, вибачте, я не можу сказати набагато більше, оскільки це пройшло деякий час. Мені подобається, android:onclickколи це зручно, але я знаю, що іноді це спричиняє проблеми, і я не можу їх пригадати :)
Uxonith

xml onClick не працює для вкладених елементів макета, які динамічно роздуваються в рівні API 19
Аміт Каушик,

1
Я рідко бачив код від інших людей, які впроваджують android: onClick, і це найбільш заплутано, коли ви переглядаєте інший код. Оскільки він не має усіх можливостей setOnClickListener, на мою думку, майже будь-хто використовує лише setOnClickListener
Крістіан

Відповіді:


122

Різниця між OnClickListener та OnClick:

  • OnClickListener - це інтерфейс, який вам потрібно реалізувати, і він може бути встановлений у вигляді в коді Java.
  • OnClickListener - це те, що чекає, поки хтось насправді натисне, onclick визначає, що відбувається, коли хтось клацає.
  • Нещодавно android додав атрибут xml до подань під назвою android: onclick, який може використовуватися для обробки кліків безпосередньо в діяльності представлення даних без необхідності реалізації будь-якого інтерфейсу.
  • Ви можете легко поміняти один варіант прослуховування іншим, якщо вам це потрібно.
  • OnClickListener дозволяє вам відокремити дію / поведінку події кліку від подання, яке ініціює подію. Хоча для простих випадків це не така велика справа, для складної обробки подій це може означати кращу читабельність та ремонтопридатність коду
  • Оскільки OnClickListener - це інтерфейс, клас, який реалізує його, має гнучкі можливості у визначенні змінних екземпляра та методів, які йому потрібні для обробки події. Знову ж таки, це не велика справа в простих випадках, але для складних випадків ми не хочемо змішувати змінні / методи, що стосуються обробки подій, з кодом подання, який ініціює подію.
  • OnClick із прив'язкою функції у XML Layout - це прив'язка між onClick та функцією, яку він буде викликати. Функція повинна мати один аргумент (View), щоб функціонувати onClick.

Обидва вони працюють однаково, лише один встановлюється через Java-код, а інший - через xml-код.

Впровадження коду 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
}

Впровадження 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 -->

Продуктивність:

Обидва однакові за роботою. Xml під час компіляції попередньо аналізується на двійковий код. отже, у Xml немає надмірностей.

Обмеження:

android: onClick призначений для API 4-го рівня, тому, якщо ви націлюєтеся на <1,6, тоді ви не можете використовувати його.


`Xml під час компіляції попередньо аналізується на двійковий код` Що саме означає це твердження? Оскільки я бачив декс-код apk, у якому є файл android: onClick у своєму файлі маніфесту, але я не знайшов жодного коду, який би явно встановив слухача
VicX

чудове пояснення. +1
Зія Ур Рахман

1
Насправді в XML є деякі накладні витрати . При натисканні на кнопку вперше, відображення використовується для визначення методу, який слід викликати . Однак це, мабуть, незначно для більшості випадків використання (а передчасна оптимізація - корінь усього зла).
Йоел,

21

Я вражений тим, що ніхто не говорив про це, але будьте обережні, хоча android:onClickXML, здається, є зручним способом обробки кліків, setOnClickListenerреалізація робить щось додаткове, ніж додавання onClickListener. Дійсно, це перетворило властивість view clickableна істину.

Незважаючи на те, що це не може бути проблемою для більшості реалізацій Android, згідно з конструктором телефону, кнопка завжди має значення за замовчуванням clickkable = true, але для інших конструкторів у певній моделі телефону за замовчуванням може бути встановлено clickable = false у некнопкових поданнях.

Отже, встановлення XML недостатньо, ви повинні весь час думати, щоб додати android:clickable="true"кнопку, яка не є кнопкою, і якщо у вас є пристрій, де за замовчуванням можна натиснути = true, і ви забули навіть один раз поставити цей атрибут XML, ви не помітите проблема під час роботи, але отримає відгук на ринку, коли вона буде в руках ваших клієнтів!

Крім того, ми ніколи не можемо бути впевнені в тому, як proguard буде затушувати та перейменовувати атрибути XML та метод класу, а значить, не на 100% безпечно, щоб одного разу вони ніколи не мали помилки.

Тож якщо ви ніколи не хочете мати проблем і ніколи про це не думайте, краще скористатися setOnClickListenerтакими бібліотеками, як ButterKnife з анотацією@OnClick(R.id.button)


1
Чи були у вас досвід (або десь десь бачили), що помилка сталася через затуманення під час використання android:onClick?
Акрам,

Спасибі пане! Ваша відповідь дуже корисна!
І Шень

12

Просто:

Якщо у вас є android:onClick = "someMethod" xml , він шукає public void someMethodу вашому класі Activity. OnClickListenerвикликається безпосередньо з вашої діяльності, і вона пов’язана з певним View. Наприклад, someButton.setOnClickListenerі в коді нижче сказано, що потрібно робити при someButtonнатисканні.

Сподіваюся, це допоможе :)


4

Як уже було сказано: обидва вони є способом додати логіку у відповідь на подію, в даному випадку подію "клацання".

Я хотів би розділити логіку від презентації, як це робиться у світі HTML / JavaScript: залиште XML для презентації та додайте прослуховувачі подій за допомогою коду.


1
Погоджено, якщо це не дуже крихітний додаток з якоюсь простою поведінкою, весь ваш виконуваний код повинен бути відокремленим та добре організованим, бажано з використанням окремих методів
OzzyTheGiant

0

Якщо у вас кілька кнопок, що використовують лише один метод, я пропоную робити це в Java. Але якщо у вас є кнопка з одним конкретним методом, onClick в XML було б краще.


0

Зручніше завжди використовувати атрибут android: onClick, якщо у вас немає вагомих причин, наприклад, якщо ви створюєте екземпляр кнопки під час виконання або вам потрібно оголосити поведінку клацання у підкласі Fragment.


3
Я рідко бачив код від інших людей, які впроваджують android: onClick, і це найбільш заплутано, коли ви переглядаєте інший код. Оскільки він не має усіх можливостей setOnClickListener, майже кожен, на мій погляд, використовує лише setOnClickListener
Крістіан

0

Є кілька причин, чому вам може знадобитися програмно встановити OnClickListener. Перший - якщо ви коли-небудь захочете змінити поведінку своєї кнопки під час запуску програми. Ви можете повністю спрямувати свою кнопку на інший спосіб, або просто відключити кнопку, встановивши параметр, OnClickListenerякий нічого не робить.

Коли ви визначаєте слухача за допомогою onClickатрибута, подання шукає метод із таким іменем лише у його діяльності на хості. Програмно встановлене значення OnClickListenerдозволяє керувати поведінкою кнопки з будь-якого місця, крім активності хосту. Це стане дуже актуальним, коли ми використовуємо Fragments, які в основному є міні-заходами, що дозволяють створювати колекції переглядів багаторазового використання зі своїм власним життєвим циклом, які потім можна об'єднати в дії. Фрагменти завжди потрібно використовувати OnClickListenersдля управління своїми кнопками, оскільки вони не є Діяльністю, і їх не буде шукати слухачі, визначені в onClick.


-2

Я думаю, що основна різниця між ними полягає в:

OnClick: Коли ви натискаєте кнопку пальцем.

OnClickListner: Це може бути ширший вибір, який буде реалізований у різних кодах.

Наприклад, коли ви вводите url "ymail.com", yahoo знаходить ваше ім'я користувача та ваш пароль у вашому браузері та вмикає кнопку стану, щоб відкрити вашу пошту. Цю дію слід реалізовувати лише в onClickListener.

Це моя ідея!


Це цікаво, але є набагато більше, ніж це; ваш скоріше повинен бути коментарем.
Dakatine
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.