Имея солидный опыт работы в области, отличной от Java и Android, я изучаю Android.
У меня много путаницы с разными областями, одна из них - как обрабатывать нажатия кнопок. Есть как минимум 4 способа сделать это (!!!), они кратко перечислены здесь
для единообразия перечислю их:
Имейте член
View.OnClickListener
класса в действии и назначьте его экземпляру, который будет обрабатыватьonClick
логику вonCreate
методе действия.Создайте onClickListener в методе действия onCreate и назначьте его кнопке с помощью setOnClickListener
Реализуйте onClickListener в самом действии и назначьте this в качестве слушателя для кнопки. В случае, если активность имеет несколько кнопок, необходимо проанализировать идентификатор кнопки, чтобы выполнить обработчик onClick для соответствующей кнопки.
Имейте общедоступный метод для действия, реализующего логику onClick, и назначьте его кнопке в объявлении xml действия.
Вопрос 1:
Это все методы, есть ли другой вариант? (Мне не нужны другие, просто любопытно)
Для меня наиболее интуитивно понятным способом был бы последний: он требует наименьшего количества кода для ввода и является наиболее читаемым (по крайней мере, для меня).
Хотя я не вижу широкого применения этого подхода. Какие минусы его использования?
Вопрос 2:
Каковы плюсы и минусы каждого из этих методов? Поделитесь, пожалуйста, своим опытом или хорошей ссылкой.
Любые отзывы приветствуются!
PS Я попытался найти в Google что-то по этой теме, но нашел только описание «как» это сделать, а не почему это хорошо или плохо.
onCreate()
, это не очень долго. Назначения прослушивателя кликов и анонимные классы могут быть выделены в отдельный вспомогательный метод, вызываемый изonCreate()
.# 1 Я часто использую последний, когда на макете есть кнопки, которые не генерируются (но, очевидно, статичны).
Если вы используете его на практике и в бизнес-приложении, обратите на это особое внимание, потому что, когда вы используете обфускатор исходного кода, такой как ProGuard, вам нужно пометить эти методы в своей деятельности, чтобы они не запутывались.
Для архивации какой-либо защиты во время компиляции с помощью этого подхода взгляните на Android Lint ( пример ).
# 2 Плюсы и минусы всех методов почти одинаковы, и урок должен быть таким:
Если вам нужно назначить одно и то же
OnClickListener
нескольким экземплярам кнопки, сохраните его в области действия класса (# 1). Если вам нужен простой слушатель для кнопки, сделайте анонимную реализацию:button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Take action. } });
Я стараюсь не реализовывать
OnClickListener
в действии, время от времени это немного сбивает с толку (особенно когда вы реализуете несколько других обработчиков событий, и никто не знает, чтоthis
все это делает).источник
Я предпочитаю вариант 4, но он имеет для меня интуитивный смысл, потому что я слишком много работаю в Grails, Groovy и JavaFX. «Магические» связи между представлением и контроллером обычны для всех. Важно правильно назвать метод:
В представлении добавьте метод onClick к кнопке или другому виджету:
android:clickable="true" android:onClick="onButtonClickCancel"
Затем в классе обработайте метод:
public void onButtonClickCancel(View view) { Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show(); }
Опять же, четко назовите метод, что-то, что вы должны делать в любом случае, и обслуживание станет второстепенным.
Одним из больших преимуществ является то, что теперь вы можете писать модульные тесты для метода. Вариант 1 может это сделать, но 2 и 3 сложнее.
источник
Наиболее распространенный способ - анонимное объявление
Button send = (Button) findViewById(R.id.buttonSend); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // handle click } });
Также вы можете создать объект View.OnClickListener и установить его на кнопку позже, но вам все равно нужно переопределить метод onClick, например
View.OnClickListener listener = new View.OnClickListener(){ @Override public void onClick(View v) { // handle click } } Button send = (Button) findViewById(R.id.buttonSend); send.setOnClickListener(listener);
Когда ваша деятельность реализует интерфейс OnClickListener, вы должны переопределить метод onClick (View v) на уровне активности. Затем вы можете назначить это действие как прослушиватель кнопки, потому что он уже реализует интерфейс и переопределяет метод onClick ()
public class MyActivity extends Activity implements View.OnClickListener{ @Override public void onClick(View v) { // handle click } @Override public void onCreate(Bundle b) { Button send = (Button) findViewById(R.id.buttonSend); send.setOnClickListener(this); } }
(imho) 4-й подход, используемый, когда несколько кнопок имеют один и тот же обработчик, и вы можете объявить один метод в классе активности и назначить этот метод нескольким кнопкам в макете xml, также вы можете создать один метод для одной кнопки, но в этом случае я предпочитают объявлять обработчики внутри класса активности.
источник
Варианты 1 и 2 включают использование внутреннего класса, который сделает код беспорядочным. Вариант 2 немного запутан, потому что на каждую кнопку будет по одному слушателю. Если у вас небольшое количество кнопок, это нормально. Для варианта 4, я думаю, это будет сложнее отладить, так как вам придется вернуться и четверть XML и Java-код. Я лично использую вариант 3, когда мне приходится обрабатывать несколько нажатий кнопок.
источник
Мой образец, протестирован в Android Studio 2.1
Определить кнопку в макете xml
<Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" />
Обнаружение пульсации Java
Button clickButton = (Button) findViewById(R.id.btn1); if (clickButton != null) { clickButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { /***Do what you want with the click here***/ } }); }
источник
Чтобы упростить задачу asp Вопрос 2, вы можете использовать лямбда-метод, подобный этому, чтобы сохранить память переменных и избежать навигации вверх и вниз в вашем классе представления.
//method 1 findViewById(R.id.buttonSend).setOnClickListener(v -> { // handle click });
но если вы хотите применить событие щелчка к вашей кнопке сразу в методе.
вы можете использовать Вопрос 3 от @D. Тран отвечает. Но не забудьте реализовать свой класс представления с помощью
View.OnClickListener
.В другом случае, чтобы правильно использовать вопрос №3
источник
Вопрос №1. Это единственный способ обрабатывать клики по просмотрам.
Вопрос №2 -
Вариант №1 / Вариант №4 - Нет большой разницы между вариантом №1 и вариантом №4. Единственное различие, которое я вижу, заключается в том, что в одном случае действие реализует OnClickListener, тогда как в другом случае будет анонимная реализация.
Вариант №2 - в этом методе будет создан анонимный класс. Этот метод немного громоздок, так как вам придется делать это несколько раз, если у вас несколько кнопок. Для анонимных классов нужно быть осторожным при обработке утечек памяти.
Вариант №3 - Впрочем, это простой способ. Обычно программисты стараются не использовать какой-либо метод, пока он не написан, и поэтому этот метод не получил широкого распространения. Вы увидите, что в основном люди используют вариант №4. Потому что он чище с точки зрения кода.
источник
Существуют также варианты, доступные в виде различных библиотек, которые могут сделать этот процесс очень знакомым для людей, которые использовали другие инфраструктуры MVVM.
https://developer.android.com/topic/libraries/data-binding/
Показывает пример официальной библиотеки, которая позволяет привязывать кнопки следующим образом:
<Button android:text="Start second activity" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="@{() -> presenter.showList()}" />
источник
Шаг 1. Создайте XML-файл:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/btnClickEvent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me" /> </LinearLayout>
Шаг 2: Создайте MainActivity:
package com.scancode.acutesoft.telephonymanagerapp; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity implements View.OnClickListener { Button btnClickEvent; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btnClickEvent = (Button) findViewById(R.id.btnClickEvent); btnClickEvent.setOnClickListener(MainActivity.this); } @Override public void onClick(View v) { //Your Logic } }
HappyCoding!
источник