Как правильно реализовать интерфейс OnClickListener для многих кнопок?

10

Моя активность Android содержит несколько кнопок, для которых требуется OnClickListener. Я видел много разных способов сделать это, таких как:

  • Реализация интерфейса в классе деятельности
  • Создание отдельного класса, который реализует интерфейс
  • Определение анонимного внутреннего класса для каждой кнопки.

Я видел много примеров каждого подхода. Однако мне не ясно, почему один подход будет использоваться вместо другого. Являются ли различия между этими подходами стилистическими или есть причины, которые делают один подход лучше?

Слейтон
источник

Ответы:

6

Как и во многих вещах, правильный подход зависит от того, что вы пытаетесь сделать для конкретной кнопки, и что еще вы делаете с действием.

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

Интерфейс другого класса реализует :
как я уже говорил выше, я предпочитаю эту опцию, когда у меня есть несколько элементов, которые могут вызывать одно и то же событие. Расширяя приведенный выше пример, давайте добавим кнопку очистки, для которой также требуется прослушиватель щелчков. Создайте одного слушателя, который выполняет предварительные действия сохранения, и одного, который выполняет предварительные действия. Каждый слушатель добавляется только к компонентам, которые будут производить это действие.

Эта реализация имеет дополнительное преимущество, которое вы можете использовать, если вам это нужно. Преимущество состоит в том, что он предотвращает запуск события другими классами внутри вашего класса активности. Поскольку метод интерфейса должен быть открытым, любой, имеющий ссылку на класс, может запустить событие. Если вам нужен детальный контроль над тем, кто может делать то, что в приложении, отдельный класс не позволяет никому со ссылкой на действие инициировать очистку или сохранение вашей формы (или, возможно, нарушение кода, если слушатель использует источник, но делает не обрабатывать плохой ввод).

Анонимный внутренний класс реализует интерфейс :
Это действительно просто особый способ создания второго варианта использования другого класса в качестве реализации. Эта опция может еще больше ограничить, у кого есть доступ для запуска события, так как никто другой не может создать экземпляр класса. Тем не менее, я думаю, что более важным фактором между этими двумя вариантами является объем работы. Очистка нескольких текстовых полей - простая и понятная операция. Однако процесс сохранения for может включать ряд задач: вы проверяете ввод (что вам следует делать), записываете в базу данных для хранения значений и запускаете некоторые действия после сохранения. В этом случае создание отдельного класса с собственным файлом обеспечит более четкое разделение между формой ввода и обработкой данных. Это, в свою очередь, сохраняет код формы вместо большого файла с несколькими внутренними классами, вложенными внутрь.

unholysampler
источник
Вау, спасибо за ваш ответ. С точки зрения издержек, стоит ли создавать несколько классов слушателей?
Слейтон
@Slayton: всегда будут расходы, независимо от того, что вы делаете. Вопрос должен звучать так: «Имеет ли это значение для вас?» Есть вес для создания большего количества объектов, но время выполнения будет больше, если ваш слушатель должен просмотреть список источников, чтобы решить, что на самом деле делать. Если использование памяти и производительность важны для вас, вам следует профилировать код и решить, что лучше всего, исходя из ваших требований. Однако я сомневаюсь, что это будет узким местом вашего кода. Если не указано иное, принимайте решения, чтобы сделать код более понятным и лучше организованным.
unholysampler
3

Четвертый способ - установить атрибут onClick в макете:

<Button android:onClick="clickHandlerForButtonX" />

который имеет этот соответствующий метод в деятельности:

public void clickHandlerForButtonX(View v) {
    //Handle Button X here
}
Orjan
источник
Интересно, я не знал, что ты мог сделать это. Хотя, похоже, это специфический механизм работы с кнопками для Android.
Слейтон
Я обычно использую «Интерфейс реализации класса деятельности», тем не менее - таким образом, у вас есть все, что связано с кликами, в одном месте.
Орян
этот конкретный метод не работает с фрагментами.
Рахул Тивари