449 votes

En quoi l'attribut XML Android:onClick diffère-t-il exactement de setOnClickListener ?

D'après ce que j'ai lu, vous pouvez attribuer une onClick à un bouton de deux façons.

Utilisation de la android:onClick XML où vous utilisez simplement le nom d'une méthode publique avec la signature void name(View v) ou en utilisant le setOnClickListener où vous passez un objet qui implémente la méthode OnClickListener l'interface. Cette dernière nécessite souvent une classe anonyme que je n'aime pas (goût personnel) ou la définition d'une classe interne qui implémente l'interface OnClickListener .

En utilisant l'attribut XML, il suffit de définir une méthode au lieu d'une classe, donc j'ai été Je me demandais si la même chose pouvait être faite par code et non dans la présentation XML.

5 votes

J'ai lu votre problème et je pense que vous êtes coincé au même endroit que moi. Je suis tombé sur une très bonne vidéo qui m'a beaucoup aidé à résoudre mon problème. Trouvez la vidéo sur le lien suivant : youtube.com/watch?v=MtmHURWKCmg&feature=youtu.be J'espère que cela vous aidera aussi :)

9 votes

Pour ceux qui veulent gagner du temps en regardant la vidéo postée dans le commentaire ci-dessus, elle démontre simplement comment deux boutons peuvent avoir la même méthode pour son onClick dans le fichier de mise en page. Cela se fait grâce au paramètre View v . Il vous suffit de vérifier if (v == findViewById(R.id.button1 )) etc.

14 votes

@Imray Je pense qu'il est préférable d'utiliser v.getId() == R.id.button1 puisque vous n'avez pas besoin de trouver le contrôle réel et de faire une comparaison. Et vous pouvez utiliser un switch au lieu de beaucoup de "si".

643voto

Octavian Damiean Points 20620

Non, ce n'est pas possible via le code. Android implémente simplement le OnClickListener pour vous lorsque vous définissez le android:onClick="someMethod" attribut.

Ces deux extraits de code sont identiques, ils sont simplement mis en œuvre de deux manières différentes.

Mise en œuvre du code

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

Ci-dessus, vous trouverez un code d'implémentation d'un OnClickListener . Et voici l'implémentation XML.

Mise en œuvre de XML

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

En arrière-plan, Android ne fait rien d'autre que le code Java, appelant votre méthode sur un événement de clic.

Notez qu'avec le XML ci-dessus, Android recherchera le fichier onClick méthode myFancyMethod() uniquement dans l'activité en cours. Il est important de s'en souvenir si vous utilisez des fragments, car même si vous ajoutez le XML ci-dessus en utilisant un fragment, Android ne cherchera pas la balise onClick dans la méthode .java du fragment utilisé pour ajouter le XML.

Une autre chose importante que j'ai remarquée. Vous avez dit que vous ne préférez pas l'anonymat méthodes . Vous vouliez dire que vous n'aimez pas les anonymes. classes .

4 votes

Je ne suis pas un gourou de Java mais oui, je voulais dire classe anonyme. Merci pour votre réponse. Très clair.

129 votes

Notez que si vous utilisez le XML onclick, vous devez mettre la méthode onclick ( 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 gérant les clics dans le onCreateView() d'un fragment... où elle serait pas être trouvée si elle est référencée à partir de XML.

0 votes

@PeterAjtai Merci de le signaler. Vous pouvez l'ajouter à ma réponse si vous le souhaitez. Il suffit de l'éditer.

93voto

jp093121 Points 492

Quand j'ai vu la première réponse, j'ai compris que mon problème était de ne pas mettre le paramètre (View v) sur la méthode fantaisie :

public void myFancyMethod(View v) {}

Lorsque l'on essaie d'y accéder à partir du xml, on doit utiliser

android:onClick="myFancyMethod"/>

J'espère que cela aidera quelqu'un.

0 votes

C'est la meilleure réponse - J'ai eu le même problème de ne pas écrire (View v) dans la méthode...

76voto

James Points 1419

android:onClick est destiné aux API de niveau 4 et plus, donc si votre cible est < 1.6, vous ne pouvez pas l'utiliser.

34voto

Ruivo Points 441

Vérifiez si vous avez oublié de rendre la méthode publique !

1 votes

Pourquoi est-il obligatoire de le rendre public ?

4 votes

@eRaisedToX Je pense que c'est assez clair : s'il n'est pas public, il ne peut pas être appelé depuis le framework Android.

15voto

Antoine Lizée Points 662

Notez que si vous souhaitez utiliser la fonction 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 par sa chaîne de nom : android:onClick="MyFancyMethod" mais la déclaration de la méthode devrait apparaître : ...MyFancyMethod(View v) {...

Si vous essayez d'ajouter cette fonctionnalité à une élément de menu il y aura exactement la même syntaxe dans le fichier XML mais votre méthode sera déclarée comme : ...MyFancyMethod(MenuItem mi) {...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X