La especificación de los android:onClick
resultados del atributo en la Button
instancia llama setOnClickListener
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 el public Button (Context context, AttributeSet attrs, int defStyle)
constructor. Todos los atributos en la etiqueta XML se leen del paquete de recursos y se pasan AttributeSet
al constructor.
Button
La clase se hereda de la View
clase View
, lo que hace que se llame al constructor, que se encarga de configurar el controlador de devolución de llamada a través de setOnClickListener
.
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 llamando setOnClickListener
solo.
case R.styleable.View_onClick:
if (context.isRestricted()) {
throw new IllegalStateException("The android:onClick attribute cannot "
+ "be used within a restricted context");
}
final String handlerName = a.getString(attr);
if (handlerName != null) {
setOnClickListener(new OnClickListener() {
private Method mHandler;
public void onClick(View v) {
if (mHandler == null) {
try {
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
int id = getId();
String idText = id == NO_ID ? "" : " with id '"
+ getContext().getResources().getResourceEntryName(
id) + "'";
throw new IllegalStateException("Could not find a method " +
handlerName + "(View) in the activity "
+ getContext().getClass() + " for onClick handler"
+ " on view " + View.this.getClass() + idText, e);
}
}
try {
mHandler.invoke(getContext(), View.this);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Could not execute non "
+ "public method of the activity", e);
} catch (InvocationTargetException e) {
throw new IllegalStateException("Could not execute "
+ "method of the activity", e);
}
}
});
}
break;
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 utiliza Java 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:
- El método de devolución de llamada debe ser público : dado que
Java Class getMethod
se utiliza, solo se buscan funciones con especificador de acceso público. De lo contrario, esté listo para manejar la IllegalAccessException
excepción.
- Al usar Button con onClick in Fragment, la devolución de llamada debe definirse en Activity :
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.
- El método de devolución de llamada debe aceptar el parámetro Ver : ya que
Java Class getMethod
busca el método que acepta View.class
como parámetro.