De lo que he leído, puede asignar un onClick
controlador a un botón de dos maneras.
Usando el android:onClick
atributo XML donde solo usa el nombre de un método público con la firma void name(View v)
o usando el setOnClickListener
método donde pasa un objeto que implementa la OnClickListener
interfaz. Esto último a menudo requiere una clase anónima que personalmente no me gusta (gusto personal) o definir una clase interna que implemente el OnClickListener
.
Al usar el atributo XML, solo necesita definir un método en lugar de una clase, por lo que me preguntaba si lo mismo se puede hacer a través del código y no en el diseño XML.
onClick
atributo en el archivo de diseño. Esto se hace gracias al parámetroView v
. Simplemente verificaif (v == findViewById(R.id.button1
)) etc.v.getId() == R.id.button1
, ya que no tiene que encontrar el control real y hacer una comparación. Y puede usar un enswitch
lugar de muchos ifs.Respuestas:
No, eso no es posible a través del código. Android solo implementa el
OnClickListener
para usted cuando define elandroid:onClick="someMethod"
atributo.Esos dos fragmentos de código son iguales, solo implementados de dos maneras diferentes.
Implementación de código
Arriba hay una implementación de código de un
OnClickListener
. Y esta es la implementación XML.Implementación XML
En segundo plano, Android no hace nada más que el código Java, llamando a su método en un evento de clic.
Tenga en cuenta que con el XML anterior, Android buscará el
onClick
métodomyFancyMethod()
solo en la Actividad actual. Es importante recordar esto si está utilizando fragmentos, ya que incluso si agrega el XML anterior utilizando un fragmento, Android no buscará elonClick
método en el.java
archivo del fragmento utilizado para agregar el XML.Otra cosa importante que noté. Mencionaste que no prefieres métodos anónimos . Querías decir que no te gustan las clases anónimas .
fuente
myFancyMethod()
) en la Actividad actual. Esto es importante si está utilizando fragmentos, ya que la forma programática de configurar los oyentes onclick probablemente tendrá el método que maneja los clics en onCreateView () de un fragmento ... donde no se encontrará si se hace referencia desde XML.Cuando vi la respuesta principal, me di cuenta de que mi problema no era poner el parámetro (Ver v) en el método elegante:
Al intentar acceder desde el xml, uno debe usar
Espero que ayude a alguien.
fuente
android:onClick
es para API nivel 4 en adelante, por lo que si está apuntando a <1.6, entonces no puede usarlo.fuente
¡Comprueba si olvidaste hacer público el método!
fuente
La especificación de los
android:onClick
resultados del atributo en laButton
instancia llamasetOnClickListener
internamente. Por lo tanto, no hay absolutamente ninguna diferencia.Para tener una comprensión clara, veamos cómo
onClick
el marco maneja el atributo XML .Cuando se infla un archivo de diseño, se instancian todas las vistas especificadas en él. En este caso específico, la
Button
instancia se crea utilizando elpublic Button (Context context, AttributeSet attrs, int defStyle)
constructor. Todos los atributos en la etiqueta XML se leen del paquete de recursos y se pasanAttributeSet
al constructor.Button
La clase se hereda de laView
claseView
, lo que hace que se llame al constructor, que se encarga de configurar el controlador de devolución de llamada a través desetOnClickListener
.El atributo onClick definido en attrs.xml se denomina en View.java como
R.styleable.View_onClick
.Aquí está el código
View.java
que hace la mayor parte del trabajo por usted llamandosetOnClickListener
solo.Como puede ver,
setOnClickListener
se llama para registrar la devolución de llamada, como lo hacemos en nuestro código. La única diferencia es que se utilizaJava Reflection
para invocar el método de devolución de llamada definido en nuestra Actividad.Aquí están las razones de los problemas mencionados en otras respuestas:
Java Class getMethod
se utiliza, solo se buscan funciones con especificador de acceso público. De lo contrario, esté listo para manejar laIllegalAccessException
excepción.getContext().getClass().getMethod()
call restringe la búsqueda del método al contexto actual, que es Activity en caso de Fragment. Por lo tanto, el método se busca dentro de la clase Actividad y no en la clase Fragmento.Java Class getMethod
busca el método que aceptaView.class
como parámetro.fuente
Aquí hay muy buenas respuestas, pero quiero agregar una línea:
En
android:onclick
XML, Android usa la reflexión de Java detrás de escena para manejar esto.Y como se explica aquí, la reflexión siempre ralentiza el rendimiento. (especialmente en Dalvik VM). Registrarse
onClickListener
es una mejor manera.fuente
Tenga en cuenta que si desea utilizar la función onClick XML, el método correspondiente debe tener un parámetro, cuyo tipo debe coincidir con el objeto XML.
Por ejemplo, un botón estará vinculado a su método a través de su cadena de nombre:
android:onClick="MyFancyMethod"
pero la declaración del método debe mostrar:...MyFancyMethod(View v) {...
Si está intentando agregar esta característica a un elemento del menú , tendrá la misma sintaxis exacta en el archivo XML, pero su método se declarará como:
...MyFancyMethod(MenuItem mi) {...
fuente
Otra forma de configurar sus oyentes al hacer clic sería utilizar XML. Simplemente agregue el atributo android: onClick a su etiqueta.
Es una buena práctica utilizar el atributo xml "onClick" sobre una clase Java anónima siempre que sea posible.
En primer lugar, echemos un vistazo a la diferencia en el código:
Atributo XML / atributo onClick
Porción XML
Porción de Java
Clase anónima de Java / setOnClickListener
Porción XML
Porción de Java
Estos son los beneficios de usar el atributo XML sobre una clase anónima de Java:
Por supuesto, no siempre es posible usar el atributo Xml, estas son las razones por las que no lo elegiríamos:
fuente
Con Java 8, probablemente podría usar la Referencia de métodos para lograr lo que desea.
Suponga que este es su
onClick
controlador de eventos para un botón.Luego, pasa la
onMyButtonClicked
referencia del método de instancia en unasetOnClickListener()
llamada como esta.Esto le permitirá evitar definir explícitamente una clase anónima usted mismo. Sin embargo, debo enfatizar que la Referencia de métodos de Java 8 es en realidad solo un azúcar sintáctico. En realidad, crea una instancia de la clase anónima para usted (al igual que lo hizo la expresión lambda), por lo tanto, se debe tener precaución similar cuando se aplica el controlador de eventos de estilo de expresión lambda cuando se anula el registro de su controlador de eventos. Este artículo lo explica realmente bien.
PD. Para aquellos que tienen curiosidad acerca de cómo puedo usar realmente la función de lenguaje Java 8 en Android, es una cortesía de la biblioteca retrolambda .
fuente
Sí, puedes hacer tu
fragment
oactivity
implementarView.OnClickListener
y cuando inicializa sus nuevos objetos de vista en código, simplemente puede hacer
mView.setOnClickListener(this);
y esto establece automáticamente todos los objetos en vista de código para utilizar el
onClick(View v)
método que tufragment
oactivity
etc tiene.Para distinguir qué vista ha llamado al
onClick
método, puede usar una instrucción de cambio en elv.getId()
método.Esta respuesta es diferente de la que dice "No, eso no es posible a través del código"
fuente
fuente
Respaldando la respuesta de Ruivo, sí, tiene que declarar el método como "público" para poder usarlo en el onclick XML de Android: estoy desarrollando una aplicación dirigida desde el nivel de API 8 (minSdk ...) a 16 (targetSdk ...).
Estaba declarando mi método como privado y causó un error, solo declarándolo como público funciona muy bien.
fuente
Tenga cuidado, aunque
android:onClick
XML parece ser una forma conveniente de manejar el clic, lasetOnClickListener
implementación hace algo más que agregar elonClickListener
. De hecho, puso la propiedad de vistaclickable
en verdadero.Si bien puede no ser un problema en la mayoría de las implementaciones de Android, de acuerdo con el constructor del teléfono, el botón siempre es predeterminado en clickable = true, pero otros constructores en algunos modelos de teléfono pueden tener un clickable = false predeterminado en las vistas que no son Button.
Por lo tanto, establecer el XML no es suficiente, debe pensar todo el tiempo para agregar
android:clickable="true"
un botón que no sea, y si tiene un dispositivo donde el valor predeterminado es clicable = verdadero y olvida incluso una vez poner este atributo XML, no notará El problema en tiempo de ejecución, pero recibirá la retroalimentación en el mercado cuando estará 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 quieres tener problemas y nunca piensas en ello, es mejor usar
setOnClickListener
bibliotecas como ButterKnife con anotaciones@OnClick(R.id.button)
fuente
onClick
atributo XML también establececlickable = true
porque llamasetOnClickListener
en elView
interiorSupongamos que desea agregar un evento de clic como este
main.xml
En el archivo java, debe escribir un método como este.
fuente
Estoy Escribe este código en el archivo xml ...
Y escribe este código en fragmento ...
fuente
La mejor manera de hacerlo es con el siguiente código:
fuente
Para facilitarle la vida y evitar la clase anónima en setOnClicklistener (), implemente una interfaz View.OnClicklistener como se muestra a continuación:
public class YourClass extiende CommonActivity implementa View.OnClickListener, ...
esto evita:
y va directamente a:
fuente