Установка OnClickListener и обработка нажатий

Установка OnClickListener и обработка нажатий

Когда мы имеет дело с множеством кнопок в приложении, то нужно позаботиться об обработке событий. В данной статье мы рассмотрим работу с 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.

1 комментарий:

  1. Если я не ошибаюсь первый и второй случай мы создаем обработчик при помощи анонимного класса. Просто в первом случае это написано более кратко. Или я не прав?

    ОтветитьУдалить