Когда мы имеет дело с множеством кнопок в приложении, то нужно позаботиться об обработке событий. В данной статье мы рассмотрим работу с OnClickListener
, варианты создания разных обработчиков событий и возможные пути идентификации конкретной кнопки. Так же мы рассмотрим преимущества и недостатки этих подходов, в некоторых случая они очень существенны, а в некоторых нет.
setOnClickListener
метод. В параметре передается класс реализующий OnClickListener интерфейс, который имеет единственный метод onClick(View v)
. Установку обработчика для кнопок следует выполнять в onCreate()
методе Activity.
Анонимный класс
Самый простой способ создания обработчика это использование анонимного класса.
mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // ... } });
Преимуществом такого подхода является простота и не требует создания дополнительных переменных. Очень хорошо подходит, если у вас только одна кнопка. Недостатками является внутренняя реализация, обработчик нельзя задать в другом месте и при наличии нескольких кнопок, такой подход становиться массивным. Так же недостатком является то, что обработчик будет использоваться только данной кнопкой.
Поле типа OnClickListener
Вместо анонимного класса мы может определить поле с типа OnClickListener
и сразу же его инициализировать:
private OnClickListener mButtonClickListener = new OnClickListener() { @Override public void onClick(View v) { // ... } };
Здесь мы получает одновременное определение и реализацию. Далее созданное поле можно передать кнопке в качестве обработчика:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mButton.setOnClickListener(mButtonClickListener); }
По сравнению с анонимными классом, использовать поле типа OnClickListener
более удобнее. Преимуществом является легкая установка обработчика сразу нескольким кнопкам и одновременное определение с реализацией. Реализация может располагаться в любом месте. Недостатком является создание поля, а именно экземпляра класса и при этом, он может иметь другие методы, но они будут не видны из вне.
Вложенный класс
При таком подходе создается вложенный класс реализующий OnClickListener интерфейс:
private class ButtonClickListener implements OnClickListener { @Override public void onClick(View v) { // ... } }
После создание класса обработчика, его можно установить для каждой кнопки следующим образом:
private ButtonClickListener mButtonClickListener; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mButtonClickListener = new ButtonClickListener(); mButton.setOnClickListener(mButtonClickListener); }
Преимуществом является простая установка в setOnClickListener
методе и то, что класс может иметь другие методы, к которым можно обращается. Недостатком является обязательное определение класса и отведение отдельного поля для хранения созданного экземпляра.
Activity с реализацией OnClickListener
Activity может сама реализовывать интерфейс OnClickListener
, тогда при установки обработчика передается this
. Сначала нужно сообщить, что Activity будет реализовывать интерфейс:
public class MainActivity extends Activity implements OnClickListener { @Override public void onClick(View v) { // ... } }
Чтобы установить обработчик, нужно передать this
нашей Activity в качестве параметра:
mButton.setOnClickListener(this);
Если с кнопкой в дальнейшем не производиться никаких действий, то можно не создавать ее экземпляр и установка обработчика будет следующей:
findViewById(R.id.about).setOnClickListener(this);
Если нужно установить обработчик во внутреннем классе, то нужно передать в качестве параметра MainActivity.this
.
findViewById(R.id.about).setOnClickListener(MainActivity.this);
Такой подход обработки нажатий более простой, удобный и наиболее предпочтительный, а так же не создает дополнительных полей или классов.
Использование одного обработчика
Было бы не разумно создавать для каждой кнопки свой обработчик, а постараться использовать уже созданный. Для определения конкретной нажатой кнопки, можно использовать getId() метод. Этот метод будет возвращать идентификатор нажатой кнопки, а мы сможем выполнить дальнейшею логику соответственно кнопки:
@Override public void onClick(View v) { switch(v.getId()) { case R.id.home: // ... break; case R.id.message: // ... break; case R.id.email: // ... break; } }
Вы можете использовать фигурные скобки для лучшего разделения кода:
@Override public void onClick(View v) { switch (v.getId()) { case R.id.about: { // ... break; } case R.id.abs__action_bar: { // ... break; } case R.id.abs__action_bar_container: { // ... break; } } }
Рассмотренные подходы обработки нажатий можно применять не только для кнопок, но и для других элементов, например таких как ListView и GridView.
Если я не ошибаюсь первый и второй случай мы создаем обработчик при помощи анонимного класса. Просто в первом случае это написано более кратко. Или я не прав?
ОтветитьУдалить