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 и функцией, которую он будет вызывать. Функция должна иметь один аргумент (представление), чтобы 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 предварительно анализируется в двоичный код при компиляции` Что именно означает этот оператор? Поскольку я видел dexcode apk, который имеет android: onClick в его файле манифеста, но я не нашел никакого кода, который явно устанавливал бы слушателя
VicX

потрясающее объяснение. +1
Зия Ур Рахман

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

21

Я шокирован, что никто не говорил об этом, но будьте осторожны, хотя android:onClickXML кажется удобным способом обработки щелчков, setOnClickListenerреализация делает что-то дополнительное, чем добавление onClickListener. В самом деле, он присвоил свойству представления clickableзначение true.

Хотя это может не быть проблемой для большинства реализаций Android, согласно конструктору телефона, button всегда по умолчанию имеет значение clickable = true, но другие конструкторы на некоторых моделях телефона могут иметь значение по умолчанию clickable = false в представлениях без кнопок.

Таким образом, установки XML недостаточно, вам нужно все время думать, чтобы добавить android:clickable="true"не кнопку, и если у вас есть устройство, на котором по умолчанию используется clickable = 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 01

0

Если у вас есть несколько кнопок, использующих только один метод, я предлагаю сделать это в java. Но если у вас есть кнопка с одним конкретным методом, лучше использовать onClick в XML.


0

Удобнее всегда использовать атрибут android: onClick, если у вас нет веской причины не делать этого, например, если вы создаете экземпляр Button во время выполнения или вам нужно объявить поведение щелчка в подклассе Fragment.


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

0

Есть несколько причин, по которым вы можете захотеть программно установить OnClickListener. Во-первых, если вы когда-нибудь захотите изменить поведение своей кнопки во время работы приложения. Вы можете полностью указать кнопку на другой метод или просто отключить кнопку, установив, OnClickListenerчто ничего не делает.

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


-2

Думаю, главное различие между ними:

OnClick: при нажатии на кнопку пальцем.

OnClickListner: это может быть более широкий выбор, который может быть реализован в различных кодах.

Например, когда вы набираете url «ymail.com», yahoo находит ваше имя пользователя и пароль в вашем браузере и активирует кнопку состояния щелчка, чтобы открыть вашу почту. Это действие должно быть реализовано только в onClickListener.

Это моя идея!


Это интересно, но это еще не все; ваш должен был быть скорее комментарием.
Дакатин
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.