Spécification des android:onClickrésultats d'attribut lors de l' Buttonappel d'instancesetOnClickListener interne. Il n'y a donc absolument aucune différence.
Pour bien comprendre, voyons comment XML onClick attribut est géré par le framework.
Lorsqu'un fichier de disposition est gonflé, toutes les vues qui y sont spécifiées sont instanciées. Dans ce cas spécifique, l' Buttoninstance est créée à l'aide du public Button (Context context, AttributeSet attrs, int defStyle)constructeur. Tous les attributs de la balise XML sont lus à partir du bundle de ressources et transmis AttributeSetau constructeur.
ButtonLa classe est héritée de la Viewclasse qui entraîne l' Viewappel du constructeur, qui prend en charge la définition du gestionnaire de rappel de clic via setOnClickListener.
L'attribut onClick défini dans attrs.xml est appelé dans View.java R.styleable.View_onClick.
Voici le code View.javaqui fait la plupart du travail pour vous en appelant setOnClickListenerpar lui-même.
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;
Comme vous pouvez le voir, setOnClickListenerest appelé pour enregistrer le rappel, comme nous le faisons dans notre code. La seule différence est qu'il utiliseJava Reflection pour appeler la méthode de rappel définie dans notre activité.
Voici la raison des problèmes mentionnés dans d'autres réponses:
- La méthode de rappel doit être publique : depuis qu'elle
Java Class getMethodest utilisée, seules les fonctions avec spécificateur d'accès public sont recherchées. Sinon, soyez prêt à gérer l' IllegalAccessExceptionexception.
- Lors de l'utilisation de Button avec onClick dans Fragment, le rappel doit être défini dans Activity :
getContext().getClass().getMethod()call restreint la recherche de méthode au contexte actuel, qui est Activity en cas de Fragment. Par conséquent, la méthode est recherchée dans la classe Activity et non dans la classe Fragment.
- La méthode de rappel doit accepter le paramètre View : puisque
Java Class getMethodrecherche la méthode qui accepte View.classcomme paramètre.