Android onClick en XML frente a OnClickListener

86

Me doy cuenta de que antes se ha hecho una pregunta con una redacción similar, pero esta es diferente. Soy bastante nuevo en el desarrollo de aplicaciones de Android y tengo tres preguntas sobre las diferencias entre el android:onclick=""atributo XML y el setOnClickListenermétodo.

  1. ¿Cuáles son las diferencias entre los dos? ¿Se encuentra la diferencia entre las dos implementaciones en tiempo de compilación, en tiempo de ejecución o en ambos?

  2. ¿Qué casos de uso son favorables a qué implementación?

  3. ¿Qué diferencia (s) hace el uso de fragmentos en Android en la elección de implementación?

KG6ZVP
fuente
1
Para el n. ° 2: debe tener cuidado al usar el xml, onclickya que debe asegurarse de que todas las clases implementen ese método. Esto es asumiendo que está utilizando el diseño más de una vez. Sin embargo, si tuviera una interfaz java para asegurarse de que el método estuviera en todas las clases que lo implementaron, no tendría que preocuparse.
Uxonith
¿No sería más o menos lo mismo tener una interfaz Java como la que describiste que extender o implementar OnClickListener?
KG6ZVP
He investigado esto antes y creo que hay un poco más que preferencia, pero lamento no poder decir mucho más porque ha pasado un tiempo. Me gusta android:onclickcuando es conveniente, pero sé que a veces ha causado problemas, y tampoco puedo recordarlos :)
Uxonith
xml onClick no funciona para elementos de diseño anidados que se inflan dinámicamente en el nivel de API 19
Amit Kaushik
1
Rara vez he visto código de otras personas que implementan android: onClick y es más confuso cuando miras el código de otra persona. Como no tiene todas las posibilidades de setOnClickListener, casi todos usan solo setOnClickListener en mi opinión
Christian

Respuestas:

122

Diferencia entre OnClickListener vs OnClick:

  • OnClickListener es la interfaz que necesita implementar y se puede configurar en una vista en código java.
  • OnClickListener es lo que espera a que alguien haga clic, onclick determina qué sucede cuando alguien hace clic.
  • Últimamente, Android agregó un atributo xml a las vistas llamado android: onclick, que se puede usar para manejar los clics directamente en la actividad de la vista sin necesidad de implementar ninguna interfaz.
  • Puede intercambiar fácilmente una implementación de oyente con otra si es necesario.
  • Un OnClickListener le permite separar la acción / comportamiento del evento de clic de la Vista que desencadena el evento. Si bien para casos simples esto no es tan importante, para el manejo de eventos complejos, esto podría significar una mejor legibilidad y mantenimiento del código.
  • Dado que OnClickListener es una interfaz, la clase que la implementa tiene flexibilidad para determinar las variables de instancia y los métodos que necesita para manejar el evento. Nuevamente, esto no es un gran problema en casos simples, pero para casos complejos, no queremos mezclar necesariamente las variables / métodos relacionados con el manejo de eventos con el código de la Vista que desencadena el evento.
  • El onClick con enlace de función en XML Layout es un enlace entre onClick y la función a la que llamará. La función debe tener un argumento (la Vista) para que onClick funcione.

Ambos funcionan de la misma manera, solo que uno se configura a través del código Java y el otro a través del código XML.

Implementación del código setOnClickListener:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

Implementación XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

Actuación:

Ambos son iguales en rendimiento. Xml se analiza previamente en código binario durante la compilación. por lo que no hay gastos generales en Xml.

Limitación:

android: onClick es para el nivel de API 4 en adelante, por lo que si su objetivo es <1.6, no puede usarlo.

Jebasuthan
fuente
`Xml se analiza previamente en código binario mientras se compila` ¿Qué significa exactamente esta declaración? Desde que vi el dexcode de un apk que tiene android: onClick en su archivo de manifiesto, pero no encontré ningún código que estableciera
VicX
impresionante explicación. +1
Zia Ur Rahman
1
De hecho, hay algunos gastos generales en XML . Cuando se hace clic en el botón por primera vez, se utiliza la reflexión para determinar el método que debe invocarse . Sin embargo, esto probablemente sea insignificante para la mayoría de los casos de uso (y la optimización prematura es la raíz de todos los males).
Yoel
21

Me sorprende que nadie haya hablado de esto, pero tenga cuidado, aunque android:onClickXML parece ser una forma conveniente de manejar el clic, la setOnClickListenerimplementación hace algo más que agregar el onClickListener. De hecho, puso la propiedad view clickableen true.

Si bien puede que no sea un problema en la mayoría de las implementaciones de Android, según el constructor del teléfono, el botón siempre es predeterminado para hacer clic = verdadero, pero otros constructores en algunos modelos de teléfono pueden tener un clic predeterminado = falso en vistas que no son de botón.

Entonces, configurar el XML no es suficiente, debe pensar todo el tiempo para agregar android:clickable="true"un botón no, y si tiene un dispositivo donde el valor predeterminado es hacer clic = verdadero y olvida incluso una vez poner este atributo XML, no lo notará el problema en tiempo de ejecución, pero obtendrá la retroalimentación en el mercado cuando esté en manos de sus clientes.

Además, nunca podemos estar seguros de cómo proguard ofuscará y cambiará el nombre de los atributos XML y el método de clase, por lo que no es 100% seguro que nunca tendrán un error algún día.

Entonces, si nunca quiere tener problemas y nunca pensar en ello, es mejor usar setOnClickListenerbibliotecas como ButterKnife con anotación@OnClick(R.id.button)

Livio
fuente
1
¿Tuviste alguna experiencia (o has visto en alguna parte) que el error se produjo debido a la ofuscación al usarlo android:onClick?
Akram
¡Gracias Señor! ¡Tu respuesta es muy útil!
Yi Shen
12

Simplemente:

Si lo tiene android:onClick = "someMethod" en xml , busca el public void someMethoden su clase Activity. OnClickListenerse llama directamente desde su Actividad y está vinculado a algún archivo View. Por ejemplo someButton.setOnClickListenery en el código siguiente se dice lo que hay que hacer cuando someButtonse presiona.

Espero eso ayude :)

mariscal
fuente
4

Como se dijo antes: ambos son una forma de agregar lógica en respuesta a un evento, en este caso un evento de 'clic'.

Yo optaría por una separación entre la lógica y la presentación, como hacemos en el mundo HTML / JavaScript: dejar el XML para la presentación y agregar oyentes de eventos mediante código.

Stephan van Hoof
fuente
1
De acuerdo, a menos que sea una aplicación muy pequeña con un comportamiento simple, todo su código de ejecución debe mantenerse separado y bien organizado, preferiblemente usando métodos separados
OzzyTheGiant
0

Si tiene varios botones con un solo método, le sugiero que lo haga en java. Pero si tiene un botón con un método específico, onClick en XML sería mejor.

Megas
fuente
0

Es más conveniente usar siempre el atributo android: onClick a menos que tenga una buena razón para no hacerlo, por ejemplo, si crea una instancia del botón en tiempo de ejecución o si necesita declarar el comportamiento del clic en una subclase de Fragmento.

Mustapha Hadid
fuente
3
Rara vez he visto código de otras personas que implementan android: onClick y es más confuso cuando miras el código de otra persona. Como no tiene todas las posibilidades de setOnClickListener, casi todos usan solo setOnClickListener en mi opinión
Christian
0

Hay un par de razones por las que es posible que desee establecer mediante programación un OnClickListener. La primera es si alguna vez desea cambiar el comportamiento de su botón mientras se ejecuta su aplicación. Puede apuntar su botón a otro método por completo, o simplemente deshabilitar el botón configurando un OnClickListenerque no hace nada.

Cuando define un oyente utilizando el onClickatributo, la vista busca un método con ese nombre solo en su actividad de host. La configuración programática de un le OnClickListenerpermite controlar el comportamiento de un botón desde otro lugar que no sea su actividad de host. Esto será muy relevante cuando usemos Fragments, que son básicamente mini actividades, lo que le permite crear colecciones reutilizables de vistas con su propio ciclo de vida, que luego se pueden ensamblar en actividades. Los fragmentos siempre deben usarse OnClickListenerspara controlar sus botones, ya que no son actividades y no se buscarán los oyentes definidos en onClick.

Rohan Vachhani
fuente
-2

Creo que la principal diferencia entre ellos es:

OnClick: cuando hace clic en el botón con el dedo.

OnClickListner: Puede ser una opción más amplia que se implemente en varios códigos.

Por ejemplo, cuando escribe url "ymail.com", Yahoo busca su nombre de usuario y contraseña en su navegador y habilita el botón de estado de clic para abrir su correo. Esta acción debe implementarse solo en onClickListener.

¡Esta es mi idea!

Seyyed Mahmood Ahmadi
fuente
Esto es interesante pero hay mucho más que eso; el tuyo debería ser un comentario.
Dakatine