La especificación de los android:onClickresultados del atributo en la Buttoninstancia llama setOnClickListenerinternamente. Por lo tanto, no hay absolutamente ninguna diferencia.
Para tener una comprensión clara, veamos cómo onClickel 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 Buttoninstancia 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 AttributeSetal constructor.
ButtonLa clase se hereda de la Viewclase 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.javaque hace la mayor parte del trabajo por usted llamando setOnClickListenersolo.
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, setOnClickListenerse llama para registrar la devolución de llamada, como lo hacemos en nuestro código. La única diferencia es que se utiliza Java Reflectionpara 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 getMethodse utiliza, solo se buscan funciones con especificador de acceso público. De lo contrario, esté listo para manejar la IllegalAccessExceptionexcepció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 getMethodbusca el método que acepta View.classcomo parámetro.