6 votes

Meilleures pratiques pour l'implémentation de l'onClickListener dans Android

Il existe quatre façons d'ajouter un onClickListener à une vue cliquable (un bouton, par exemple) :

  1. définir l'attribut onClick dans le fichier de présentation qui pointe vers une méthode de l'activité,
  2. créer une classe interne anonyme,
  3. assigner le onClickListener à une variable membre privée.
  4. que le contexte Activity implémente l'interface onClickListener.

Ma question est donc la suivante : comment choisir une de ces techniques de mise en œuvre plutôt qu'une autre ? Existe-t-il une meilleure pratique en fonction de certaines conditions, ou est-ce simplement une question de préférence du programmeur ?

4voto

Maxim G Points 1371

Nous utilisons ici ce que l'on appelle le modèle de rappel.

public class Button {
    private Callback callback;

    public Button(Callback callback) {
        this.callback = callback;
    }

    public void update() {
        // Check if clicked..
        callback.onClick(this);
    }

    public interface Callback {
        public void onClick(Button Button);
    }
}

Button b = new Button(new Callback() {
    @Override
    public void onClick(Button b) {
        System.out.println("Clicked");
    }
});

Dans notre cas, le gestionnaire onClick implémente l'interface View.OnClickListener.

Points clés :

  • cohérence avec l'activité/fragment ;
  • accès aux membres de l'activité/fragment ;
  • la lisibilité ;
  • @Michael Krause un autre bien point de ce point de vue fuites de mémoire ;

1) L'attribut dans le fichier XML ne peut être utilisé que pour l'activité, en tant que @Karakuri mentionné qu'il utilise la réflexion, ce qui est lent.

2) La classe interne anonyme a des règles spéciales pour l'accès aux membres de la classe englobante (vérifier [1] , [2] ). Il existe certaines situations où des fuites de mémoire peuvent se produire (ex. threading avec AsyncTask, Handlers).

3) Ici, vous avez un accès complet aux membres de la classe englobante.

4) Est une variation de 3d.

La lisibilité dépend de la taille de votre gestionnaire. Une petite logique peut être acceptée en ligne, mais pour des blocs de code plus importants, envisagez la 3d et la 4e.

2voto

Karakuri Points 11241

Je n'utilise jamais le onClick car il lie la disposition à une activité spécifique (il doit trouver la méthode par réflexion). Cela ne fonctionne pas sur les fragments.

Les options 2 et 3 sont pratiquement identiques. L'option 3 pourrait être plus avantageuse si vous voulez utiliser le député comme le OnClickListener de vues multiples.

L'option 4 est proche de l'option 3. Une différence essentielle est qu'elle modifie la déclaration de la classe. Par conséquent, si vous tenez à ce que la déclaration de la classe soit exempte d'implémentations d'interfaces (ou si vous devez maintenir une compatibilité binaire quelconque), vous ne voudrez peut-être pas utiliser cette option.

Je vous conseille d'éviter l'option 1 et de choisir celle qui correspond le mieux à votre style de code. Vous n'êtes pas non plus obligé d'utiliser la même approche à chaque endroit de votre code.

0voto

Dumbo Points 901

Il y a quatre façons d'utiliser OnClickListener .

Premier moyen

Pour définir OnClickListener dans le site d'appel de la méthode.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.myButton);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                // do something
            }
        });
    }
}  

La première raison pour laquelle il faut éviter cela est que cela encombre onCreate méthode. Cela devient encore plus évident lorsque vous voulez observer les événements de clics de plusieurs vues.
La raison suivante pour éviter cela est que cela ne favorise pas la réutilisation du code si plusieurs boutons doivent faire la même chose.

Deuxième voie

La deuxième méthode est presque la même que la première, sauf que l'implémentation dans le champ est assignée dans la classe.

public class MainActivity extends AppCompatActivity {

    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // do something
        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.myButton);
        button.setOnClickListener(clickListener);
    }
}  

Cette méthode est à peu près la même que la première, le seul avantage étant que la méthode peut être réutilisée pour plusieurs boutons.

Troisième voie

Cette façon de faire consiste à déclarer une classe interne pour implémenter OnClickListener . Si elle doit être utilisée plusieurs fois, il est préférable de définir l'instance comme un champ.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.myButton);
        button.setOnClickListener(new ButtonClick());
    }

    class ButtonClick implements View.OnClickListener {
        @Override
        public void onClick(View v) {
            // do something
        }
    }
}  

L'avantage de cette méthode est qu'elle permet d'organiser le code. Vous pouvez facilement réduire cette classe interne et l'oublier jusqu'à ce que vous ayez besoin de la consulter.
L'autre bonne raison est qu'il pourrait être transformé en classe publique et réutilisé dans d'autres domaines d'application.

Quatrième voie

La quatrième voie consiste à mettre en œuvre des activités OnClickListener .

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button button = findViewById(R.id.myButton);
        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // do something
    }
}  

Le premier inconvénient de cette méthode est qu'elle crée une méthode publique dans l'activité et que vous devez y passer this activité lorsque setOnClickListener s'appelle.
La deuxième raison d'éviter cette méthode est que si un autre bouton est ajouté, vous devez déterminer quel bouton a été cliqué. Vous devez alors utiliser switch() ou if() déclarations. Il n'est pas exécuté parce qu'il gaspille un cycle ou plusieurs pour chaque clic de bouton.
Le dernier inconvénient de cette méthode est qu'il est difficile d'organiser une classe. Par exemple, vous avez une activité qui implémente plusieurs interfaces. Soudainement, toutes les méthodes de ces interfaces sont entrelacées ensemble, ce qui devient plus évident après avoir ajouté des méthodes à certaines de ces interfaces. De plus, vous ne pouvez plus ajouter une interface avec une méthode nommée onClick .

Il y a quelques différences entre ces méthodes, mais vous devez choisir votre méthode en fonction de votre code et de vos besoins.

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