Android: cómo manejar el clic del botón

Al tener una sólida experiencia en áreas que no son de Java ni de Android, estoy aprendiendo sobre Android.

Tengo mucha confusión con diferentes áreas, una de ellas es cómo manejar los clics de los botones. Hay al menos 4 formas de hacerlo (!!!), se enumeran brevemente aquí

para fines de coherencia, los incluiré en una lista:

  1. Tenga un miembro de la clase View.OnClickListener en la actividad y View.OnClickListener a una instancia que manejará la lógica onCreate en el método de actividad onCreate .

  2. Cree ‘onClickListener’ en el método de actividad ‘onCreate’ y asígnelo al botón usando setOnClickListener

  3. Implemente ‘onClickListener’ en la actividad en sí y asigne ‘this’ como un oyente para el botón. En el caso de que la actividad tenga pocos botones, se debe analizar la id del botón para ejecutar el manejador ‘onClick’ para el botón apropiado.

  4. Tener un método público en la actividad que implementa la lógica ‘onClick’ y asignarlo al botón en la statement xml de actividad

Pregunta 1:

Son todos esos métodos, ¿hay alguna otra opción? (No necesito otro, solo curiosidad)

Para mí, la forma más intuitiva sería la última: requiere la menor cantidad de código para ser tipeada y es la más legible (al menos para mí).

Sin embargo, no veo este enfoque ampliamente utilizado. ¿Cuáles son los contras para usarlo?

Pregunta 2:

¿Cuáles son los pros / contras para cada uno de estos métodos? Por favor comparta su experiencia o un buen enlace.

Cualquier comentario es bienvenido!

PD. He intentado buscar en Google y encontrar algo para este tema, pero las únicas cosas que encontré son la descripción de “cómo” hacer eso, no por qué es bueno o malo.

Pregunta 1: Desafortunadamente, la que usted dice que es más intuitiva es la menos utilizada en Android. Según tengo entendido, debe separar su UI (XML) y su funcionalidad computacional (Java Class Files). También facilita la depuración. En realidad, es mucho más fácil leer de esta manera y pensar en Android imo.

Pregunta 2: Creo que los dos utilizados principalmente son # 2 y # 3. Usaré un Button clickButton como ejemplo.

2

está en la forma de una clase anónima.

 Button clickButton = (Button) findViewById(R.id.clickButton); clickButton.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub ***Do what you want with the click here*** } }); 

Este es mi favorito ya que tiene el método onClick justo al lado de donde se configuró la variable del botón con findViewById. Parece muy limpio y ordenado que todo lo que se refiere a esta vista de botón de clic se encuentre aquí.

Una estafa que mi compañero de trabajo comenta, es que imagina que tiene muchos puntos de vista que necesitan un oyente de clic. Puedes ver que tu onCreate tendrá una longitud muy larga. Entonces, por eso le gusta usar:

3

Digamos que tienes, 5 clickButtons:

Asegúrate de que tu Actividad / Fragmento implemente OnClickListener

 // in OnCreate Button mClickButton1 = (Button)findViewById(R.id.clickButton1); mClickButton1.setOnClickListener(this); Button mClickButton2 = (Button)findViewById(R.id.clickButton2); mClickButton2.setOnClickListener(this); Button mClickButton3 = (Button)findViewById(R.id.clickButton3); mClickButton3.setOnClickListener(this); Button mClickButton4 = (Button)findViewById(R.id.clickButton4); mClickButton4.setOnClickListener(this); Button mClickButton5 = (Button)findViewById(R.id.clickButton5); mClickButton5.setOnClickListener(this); // somewhere else in your code public void onClick(View v) { switch (v.getId()) { case R.id.clickButton1: { // do something for button 1 click break; } case R.id.clickButton2: { // do something for button 2 click break; } //.... etc } } 

De esta forma, como explica mi compañero de trabajo, es más limpio en sus ojos, ya que todo el cálculo de OnClick se maneja en un solo lugar y no satura el método onCreate. Pero la desventaja que veo es que:

  1. se ve a sí mismo,
  2. y cualquier otro objeto que pueda estar ubicado en onCreate utilizado por el método onClick tendrá que convertirse en un campo.

Avíseme si desea obtener más información. No respondí tu pregunta completamente porque es una pregunta bastante larga. Y si encuentro algunos sitios ampliaré mi respuesta, en este momento solo estoy dando algo de experiencia.

# 1 Utilizo el último con frecuencia cuando tengo botones en el diseño que no se generan (pero estático obviamente).

Si lo usa en la práctica y en una aplicación comercial, preste especial atención aquí, porque cuando use el obfuscater original como ProGuard, tendrá que marcar estos métodos en su actividad para no ofuscarse.

Para archivar algún tipo de seguridad en tiempo de comstackción con este enfoque, eche un vistazo a Android Lint ( ejemplo ).


# 2 Las ventajas y desventajas de todos los métodos son casi iguales y la lección debería ser:

Usa lo que sea más apropiado o lo que más te resulte intuitivo.

Si tiene que asignar el mismo OnClickListener a varias instancias de botón, guárdelo en el ámbito de clase (n. ° 1). Si necesita un oyente simple para un Botón, realice una implementación anónima:

 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Take action. } }); 

OnClickListener a no implementar OnClickListener en la actividad, esto se vuelve un poco confuso de vez en cuando (especialmente cuando implementa muchos otros manejadores de eventos y nadie sabe qué está haciendo).

Prefiero la opción 4, pero tiene un sentido intuitivo para mí porque trabajo demasiado en Grails, Groovy y JavaFX. Las conexiones “mágicas” entre la vista y el controlador son comunes en todos. Es importante nombrar bien el método:

En la vista, agregue el método onClick al botón u otro widget:

  android:clickable="true" android:onClick="onButtonClickCancel" 

Luego, en la clase, maneja el método:

 public void onButtonClickCancel(View view) { Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show(); } 

Una vez más, nombre el método claramente, algo que debe hacer de todos modos, y el mantenimiento se convierte en una segunda naturaleza.

Una gran ventaja es que ahora puede escribir pruebas unitarias para el método. La opción 1 puede hacer esto, pero 2 y 3 son más difíciles.

La forma más utilizada es la statement anónima

  Button send = (Button) findViewById(R.id.buttonSend); send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // handle click } }); 

También puede crear el objeto View.OnClickListener y establecerlo en el botón más tarde, pero aún debe reemplazar el método OnClick, por ejemplo

 View.OnClickListener listener = new View.OnClickListener(){ @Override public void onClick(View v) { // handle click } } Button send = (Button) findViewById(R.id.buttonSend); send.setOnClickListener(listener); 

Cuando su actividad implemente la interfaz OnClickListener, debe anular el método onClick (Ver v) en el nivel de actividad. Luego puede asignar esta actividad como botón de oyente a, porque ya implementa la interfaz y anula el método 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º enfoque utilizado cuando varios botones tienen el mismo controlador, y puede declarar un método en clase de actividad y asignar este método a varios botones en el diseño xml, también puede crear un método para un botón, pero en este caso yo Prefiero declarar manejadores dentro de la clase de actividad.

Las opciones 1 y 2 implican el uso de la clase interna que hará que el código sea un poco desordenado. La opción 2 es un poco desordenada porque habrá un oyente por cada botón. Si tiene un número pequeño de botones, está bien. Para la opción 4, creo que esto será más difícil de depurar, ya que tendrá que volver atrás y el cuarto código xml y java. Yo personalmente uso la opción 3 cuando tengo que manejar múltiples clics de botón.

Mi ejemplo, probado en el estudio Android 2.1

Definir el botón en el diseño xml

  

Detección de pulsaciones de 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***/ } }); } 

Para facilitar las cosas, la Pregunta 2 dice que puede utilizar el método lambda de esta manera para guardar la memoria variable y evitar navegar hacia arriba y hacia abajo en su clase de vista

 //method 1 findViewById(R.id.buttonSend).setOnClickListener(v -> { // handle click }); 

pero si desea aplicar clic evento a su botón de una vez en un método.

puede hacer uso de la Pregunta 3 por @D. Tran respuesta. Pero no olvide implementar su clase de vista con View.OnClickListener .

En otro para usar la Pregunta # 3 apropiadamente

Pregunta n. ° 1: esta es la única forma de manejar clics de vista.

Pregunta 2 –
Opción n. ° 1 / Opción n. ° 4: no hay mucha diferencia entre la opción n. ° 1 y la opción n. ° 4. La única diferencia que veo es que en un caso la actividad es implementar OnClickListener, mientras que, en el otro caso, habría una implementación anónima.

Opción n. ° 2: en este método se generará una clase anónima. Este método es un poco abrumador, ya que tendrías que hacerlo varias veces si tienes varios botones. Para las clases Anónimas, debe tener cuidado para manejar memory leaks.

Opción # 3 – Sin embargo, esta es una manera fácil. Por lo general, los progtwigdores intentan no utilizar ningún método hasta que lo escriben y, por lo tanto, este método no se usa ampliamente. Verás que la mayoría de la gente usa la Opción # 4. Porque es más limpio en términos de código.

También hay opciones disponibles en forma de varias bibliotecas que pueden hacer que este proceso sea muy familiar para las personas que han utilizado otros marcos MVVM.

https://developer.android.com/topic/libraries/data-binding/

Muestra un ejemplo de una biblioteca oficial, que le permite vincular botones como este:

  

Paso 1: crea un archivo XML:

 < ?xml version="1.0" encoding="utf-8"?>    

Paso 2: Crear actividad principal:

 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!