Spécification des android:onClick
résultats d'attribut lors de l' Button
appel 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' Button
instance 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 AttributeSet
au constructeur.
Button
La classe est héritée de la View
classe qui entraîne l' View
appel 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.java
qui fait la plupart du travail pour vous en appelant setOnClickListener
par 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, setOnClickListener
est 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 getMethod
est utilisée, seules les fonctions avec spécificateur d'accès public sont recherchées. Sinon, soyez prêt à gérer l' IllegalAccessException
exception.
- 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 getMethod
recherche la méthode qui accepte View.class
comme paramètre.