D'après ce que j'ai lu, vous pouvez affecter un onClick
gestionnaire à un bouton de deux manières.
En utilisant l' android:onClick
attribut XML où vous utilisez simplement le nom d'une méthode publique avec la signature void name(View v)
ou en utilisant la setOnClickListener
méthode où vous passez un objet qui implémente l' OnClickListener
interface. Ce dernier nécessite souvent une classe anonyme que personnellement je n'aime pas (goût personnel) ou définissant une classe interne qui implémente le OnClickListener
.
En utilisant l'attribut XML, vous avez juste besoin de définir une méthode au lieu d'une classe, donc je me demandais si la même chose pouvait être faite via du code et non dans la disposition XML.
onClick
attribut dans le fichier de mise en page. Cela se fait grâce au paramètreView v
. Vous vérifiez simplementif (v == findViewById(R.id.button1
)) etc.v.getId() == R.id.button1
, car vous n'avez pas besoin de trouver le contrôle réel et de faire une comparaison. Et vous pouvez utiliser unswitch
au lieu de beaucoup d'if.Réponses:
Non, ce n'est pas possible via le code. Android implémente simplement le
OnClickListener
pour vous lorsque vous définissez l'android:onClick="someMethod"
attribut.Ces deux extraits de code sont égaux, juste implémentés de deux manières différentes.
Implémentation du code
Ci-dessus est une implémentation de code d'un
OnClickListener
. Et ceci est l'implémentation XML.Implémentation XML
En arrière-plan, Android ne fait rien d'autre que le code Java, appelant votre méthode lors d'un événement de clic.
Notez qu'avec le XML ci-dessus, Android ne recherchera la
onClick
méthodemyFancyMethod()
que dans l'activité en cours. Il est important de se rappeler si vous utilisez des fragments, car même si vous ajoutez le XML ci-dessus à l'aide d'un fragment, Android ne recherchera pas laonClick
méthode dans le.java
fichier du fragment utilisé pour ajouter le XML.Une autre chose importante que j'ai remarquée. Vous avez mentionné que vous ne préférez pas les méthodes anonymes . Vous vouliez dire que vous n'aimez pas les cours anonymes .
la source
myFancyMethod()
) dans l'activité en cours. Ceci est important si vous utilisez des fragments, car la manière programmatique de définir les écouteurs onclick aura probablement la méthode de gestion des clics dans onCreateView () d'un fragment ... où il ne serait pas trouvé s'il était référencé à partir de XML.Quand j'ai vu la première réponse, cela m'a fait réaliser que mon problème n'était pas de mettre le paramètre (View v) sur la méthode fantaisie:
Lorsque vous essayez d'y accéder à partir du xml, il faut utiliser
J'espère que cela aide quelqu'un.
la source
android:onClick
est pour l'API de niveau 4 et plus, donc si vous ciblez <1,6, vous ne pouvez pas l'utiliser.la source
Vérifiez si vous avez oublié de rendre la méthode publique!
la source
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 dupublic Button (Context context, AttributeSet attrs, int defStyle)
constructeur. Tous les attributs de la balise XML sont lus à partir du bundle de ressources et transmisAttributeSet
au constructeur.Button
La classe est héritée de laView
classe qui entraîne l'View
appel du constructeur, qui prend en charge la définition du gestionnaire de rappel de clic viasetOnClickListener
.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 appelantsetOnClickListener
par lui-même.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:
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.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.Java Class getMethod
recherche la méthode qui accepteView.class
comme paramètre.la source
Il y a de très bonnes réponses ici, mais je veux ajouter une ligne:
En
android:onclick
XML, Android utilise la réflexion java derrière la scène pour gérer cela.Et comme expliqué ici, la réflexion ralentit toujours la performance. (en particulier sur Dalvik VM). L'inscription
onClickListener
est une meilleure façon.la source
Notez que si vous souhaitez utiliser la fonctionnalité XML onClick, la méthode correspondante doit avoir un paramètre, dont le type doit correspondre à l'objet XML.
Par exemple, un bouton sera lié à votre méthode via sa chaîne de nom:
android:onClick="MyFancyMethod"
mais la déclaration de méthode doit afficher:...MyFancyMethod(View v) {...
Si vous essayez d'ajouter cette fonctionnalité à un élément de menu , elle aura exactement la même syntaxe dans le fichier XML mais votre méthode sera déclarée comme:
...MyFancyMethod(MenuItem mi) {...
la source
Une autre façon de définir vos écouteurs au clic serait d'utiliser XML. Ajoutez simplement l'attribut android: onClick à votre balise.
C'est une bonne pratique d'utiliser l'attribut xml «onClick» sur une classe Java anonyme dans la mesure du possible.
Tout d'abord, regardons la différence de code:
Attribut XML / attribut onClick
Partie XML
Portion Java
Classe Java anonyme / setOnClickListener
Partie XML
Portion Java
Voici les avantages de l'utilisation de l'attribut XML sur une classe Java anonyme:
Bien sûr, il n'est pas toujours possible d'utiliser l'attribut Xml, voici les raisons pour lesquelles nous ne le choisirions pas:
la source
Avec Java 8, vous pourriez probablement utiliser la référence de méthode pour obtenir ce que vous voulez.
Supposons qu'il s'agit de votre
onClick
gestionnaire d'événements pour un bouton.Ensuite, vous passez la
onMyButtonClicked
référence de méthode d'instance dans unsetOnClickListener()
appel comme celui-ci.Cela vous permettra d'éviter de définir explicitement une classe anonyme par vous-même. Je dois cependant souligner que la référence de méthode de Java 8 n'est en fait qu'un sucre syntaxique. Il crée en fait une instance de la classe anonyme pour vous (tout comme l'expression lambda), d'où la même prudence que le gestionnaire d'événements de style expression-lambda a été appliqué lorsque vous arrivez à l'annulation de l'enregistrement de votre gestionnaire d'événements. Cet article explique vraiment bien.
PS. Pour ceux qui veulent savoir comment puis-je vraiment utiliser la fonctionnalité du langage Java 8 dans Android, c'est une gracieuseté de la bibliothèque retrolambda .
la source
Oui, vous pouvez faire votre
fragment
ouactivity
mettre en œuvreView.OnClickListener
et lorsque vous initialisez vos nouveaux objets de vue dans le code, vous pouvez simplement faire
mView.setOnClickListener(this);
et cela définit automatiquement tous les objets de vue dans le code pour utiliser la
onClick(View v)
méthode que votrefragment
ouactivity
etc a.pour distinguer quelle vue a appelé la
onClick
méthode, vous pouvez utiliser une instruction switch sur lav.getId()
méthode.Cette réponse est différente de celle qui dit "Non, ce n'est pas possible via le code"
la source
la source
Soutenant la réponse de Ruivo, oui, vous devez déclarer la méthode comme "publique" pour pouvoir l'utiliser dans le onclick XML d'Android - je développe une application ciblant du niveau d'API 8 (minSdk ...) à 16 (targetSdk ...).
Je déclarais ma méthode privée et cela a provoqué une erreur, je l'ai simplement déclarée comme étant de grands travaux publics.
la source
Soyez prudent, bien que
android:onClick
XML semble être un moyen pratique de gérer les clics, l'setOnClickListener
implémentation fait quelque chose de plus que l'ajout deonClickListener
. En effet, cela a mis la propriété viewclickable
à true.Bien que cela ne soit pas un problème sur la plupart des implémentations Android, selon le constructeur du téléphone, le bouton est toujours par défaut clickable = true mais d'autres constructeurs sur certains modèles de téléphone peuvent avoir un clickable = false par défaut sur les vues non Button.
Donc, définir le XML ne suffit pas, vous devez penser tout le temps à ajouter
android:clickable="true"
sur un bouton non, et si vous avez un appareil où la valeur par défaut est clickable = true et que vous oubliez même une fois de mettre cet attribut XML, vous ne remarquerez pas le problème lors de l'exécution, mais obtiendra les commentaires sur le marché lorsqu'il sera entre les mains de vos clients!De plus, nous ne pouvons jamais être sûrs de la façon dont proguard masquera et renommera les attributs XML et la méthode de classe, donc pas sûr à 100% qu'ils n'auront jamais un bogue un jour.
Donc, si vous ne voulez jamais avoir de problèmes et n'y pensez jamais, il vaut mieux utiliser des
setOnClickListener
bibliothèques comme ButterKnife avec annotation@OnClick(R.id.button)
la source
onClick
attribut XML est également définiclickable = true
car il fait appelsetOnClickListener
à l'View
interneSupposons que vous souhaitiez ajouter un événement de clic comme celui-ci
main.xml
Dans le fichier java, vous devez écrire une méthode comme cette méthode.
la source
Je suis Écrivez ce code dans un fichier xml ...
Et écrivez ce code en fragment ...
la source
La meilleure façon de procéder consiste à utiliser le code suivant:
la source
Pour vous faciliter la vie et éviter la classe anonyme dans setOnClicklistener (), implémentez une interface View.OnClicklistener comme ci-dessous:
public class YourClass étend les implémentations CommonActivity View.OnClickListener, ...
cela évite:
et va directement à:
la source