Android: comment gérer le clic de bouton

Ayant une solide expérience dans la zone non-Java et non-Android, j'apprends Android.

J'ai beaucoup de confusion avec différents domaines, l'un d'eux est de savoir comment gérer les clics de bouton. Il y a au moins 4 façons de le faire (!!!), ils sont brièvement indiqués ici

À des fins de cohérence, je vais les énumérer:

  1. Avoir un membre de la View.OnClickListener classe de l'activité et de l'attribuer à une instance qui gère onClick logique dans le onCreate activité méthode.

  2. Créez 'onClickListener' dans la méthode d'activité 'onCreate' et affectez-le au bouton en utilisant setOnClickListener

  3. Implémentez 'onClickListener' dans l'activité elle-même et affectez 'this' en tant qu'écouteur pour le bouton. Pour le cas où l'activité a peu de boutons, l'id du bouton doit être analysé pour exécuter le gestionnaire' onClick ' pour le bouton approprié

  4. Avoir une méthode publique sur l'activité qui implémente la logique' onClick ' et l'affecter au bouton dans la déclaration XML d'activité

Question #1:

Sont-ce Toutes les méthodes, y a-t-il une autre option? (Je n'ai pas besoin d'autre, juste curieux)

Pour moi, la manière la plus intuitive serait la dernière: elle nécessite le moins de code à taper et est la plus lisible (du moins pour moi).

Cependant, je ne vois pas cette approche largement utilisée. Quels sont les inconvénients pour l'utiliser?

Question #2:

Quels sont les avantages/inconvénients chacune de ces méthodes? Veuillez partager votre expérience ou un bon lien.

Toute rétroaction est la bienvenue!

P.S. j'ai essayé de Google et de trouver quelque chose pour ce sujet, mais les seules choses que j'ai trouvées sont la description "Comment" pour le faire, pas pourquoi est-ce bon ou mauvais.

77
demandé sur Aditya Vyas-Lakhan 2013-02-09 03:15:28

10 réponses

Question 1: Malheureusement, celui dans lequel vous vous dites est le plus intuitif est le moins utilisé dans Android. Si je comprends bien, vous devez séparer votre interface utilisateur (XML) et la fonctionnalité de calcul (fichiers de classe Java). Il facilite également le débogage. Il est en fait beaucoup plus facile de lire de cette façon et de penser à Android imo.

Question 2: Je crois que les deux principalement utilisés sont #2 et # 3. Je vais utiliser un bouton clickButton comme exemple.

2

Est sous la forme d'un anonyme classe.

Button clickButton = (Button) findViewById(R.id.clickButton);
clickButton.setOnClickListener( new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                ***Do what you want with the click here***
            }
        });

C'est mon préféré car il a la méthode onClick juste à côté de l'endroit où la variable button a été définie avec findViewById. Il semble très soigné et bien rangé que tout ce qui traite de cette vue de bouton clickButton se trouve ici.

Un con que mon collègue commente, c'est que imaginez que vous avez beaucoup de points de vue qui ont besoin d'un écouteur onclick. Vous pouvez voir que votre onCreate sera très long. Alors que pourquoi il aime utiliser:

3

Dites que vous avez, 5 clickButtons:

Assurez-vous que votre activité/Fragment implémente OnClickListener

// in OnCreate

Button mClickButton1 = (Button)findViewById(R.id.clickButton1);
mClickButton1.setOnClickListener(this);
Button mClickButton2 = (Button)findViewById(R.id.clickButton2);
mClickButton2.setOnClickListener(this);
Button mClickButton3 = (Button)findViewById(R.id.clickButton3);
mClickButton3.setOnClickListener(this);
Button mClickButton4 = (Button)findViewById(R.id.clickButton4);
mClickButton4.setOnClickListener(this);
Button mClickButton5 = (Button)findViewById(R.id.clickButton5);
mClickButton5.setOnClickListener(this);


// somewhere else in your code

public void onClick(View v) {
    switch (v.getId()) {
        case  R.id.clickButton1: {
            // do something for button 1 click
            break;
        }

        case R.id.clickButton2: {
            // do something for button 2 click
            break;
        }

        //.... etc
    }
}

De cette façon, comme l'explique mon collègue, est plus propre à ses yeux, car tout le calcul onClick est géré au même endroit et ne pas encombrer la méthode onCreate. Mais l'inconvénient que je vois est que le:

  1. se voit,
  2. et tout autre objet qui pourrait être situé dans onCreate utilisé par la méthode onClick devra être transformé en un champ.

Faites-moi savoir si vous souhaitez de plus amples informations. Je n'ai pas répondu complètement à votre question parce que c'est une question assez longue. Et si je trouve des sites, je vais élargir ma réponse, en ce moment, je donne juste un peu d'expérience.

121
répondu D. Tran 2014-12-02 13:04:41

#1 j'utilise fréquemment le dernier lorsque j'ai des boutons sur la mise en page qui ne sont pas générés (mais statiques évidemment).

Si vous l'utilisez dans la pratique et dans une application métier, faites attention ici, car lorsque vous utilisez source obfuscater comme ProGuard, vous devrez marquer ces méthodes dans votre activité pour ne pas être obscurci.

Pour archiver une sorte de sécurité à la compilation avec cette approche, jetez un oeil à Android Lint (exemple).


#2 avantages et inconvénients pour le tous les méthodes sont presque les mêmes et la leçon devrait être:

Utilisez ce qui est le plus approprié ou le plus intuitif pour vous.

Si vous devez affecter le même OnClickListener à plusieurs instances de bouton, enregistrez - le dans la classe-scope (#1). Si vous avez besoin d'un écouteur simple pour un bouton, faites une implémentation anonyme:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        // Take action.
    }
});

J'ai tendance à ne pas implémenter le OnClickListener dans l'activité, ceci devient un peu déroutant de temps en temps (surtout lorsque vous implémentez plusieurs autres gestionnaires d'événements et que personne ne sait ce que this fait tous).

10
répondu Lukas Knuth 2013-02-08 23:29:34

Je préfère l'option 4, mais cela a un sens intuitif pour moi parce que je fais beaucoup trop de travail dans Grails, Groovy et JavaFX. Les connexions "magiques" entre la vue et le contrôleur sont communes dans tous. Il est important de bien nommer la méthode:

Dans la vue,ajoutez la méthode onClick au bouton ou à un autre widget:

    android:clickable="true"
    android:onClick="onButtonClickCancel"

Ensuite, dans la classe, gérez la méthode:

public void onButtonClickCancel(View view) {
    Toast.makeText(this, "Cancel pressed", Toast.LENGTH_LONG).show();
}

Encore une fois, nommez la méthode clairement, quelque chose que vous devriez faire de toute façon, et la maintenance devient une seconde nature.

Un gros avantage est que vous pouvez écrire des tests unitaires maintenant pour la méthode. L'Option 1 peut le faire, mais 2 et 3 sont plus difficiles.

7
répondu Steve Gelman 2015-12-19 17:44:32

Le moyen le plus utilisé est, déclaration anonyme

    Button send = (Button) findViewById(R.id.buttonSend);
    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // handle click
        }
    });

Vous pouvez également créer une vue.Objet OnClickListener et définissez-le sur button plus tard, mais vous devez toujours remplacer la méthode onClick par exemple

View.OnClickListener listener = new View.OnClickListener(){
     @Override
        public void onClick(View v) {
            // handle click
        }
}   
Button send = (Button) findViewById(R.id.buttonSend);
send.setOnClickListener(listener);

Lorsque votre activité implémente L'interface OnClickListener, vous devez remplacer la méthode onClick (View v) au niveau de l'activité. Ensuite, vous pouvez assing cette activité en tant qu'écouteur à button, car il implémente déjà l'interface et remplace la méthode onClick ()

public class MyActivity extends Activity implements View.OnClickListener{


    @Override
    public void onClick(View v) {
        // handle click
    }


    @Override
    public void onCreate(Bundle b) {
        Button send = (Button) findViewById(R.id.buttonSend);
        send.setOnClickListener(this);
    }

}

(à mon humble avis) de 4-ème approche utilisée lorsque plusieurs boutons ont le même gestionnaire, et vous pouvez déclarer une méthode dans la classe activity et attribuer cette méthode à plusieurs boutons dans la mise en page xml, vous pouvez également créer une méthode pour un bouton, mais dans ce cas je préfère pour déclarer les gestionnaires dans la classe d'activité.

4
répondu Georgy Gobozov 2013-08-31 08:08:13

Les options 1 et 2 impliquent l'utilisation d'une classe interne qui rendra le code plus encombrant. L'Option 2 est un peu désordonnée car il y aura un écouteur pour chaque bouton. Si vous avez un petit nombre de bouton, c'est bien. Pour l'option 4, je pense que ce sera plus difficile à déboguer car vous devrez revenir en arrière et quatrièmement le code xml et java. Personnellement, j'utilise l'option 3 quand je dois gérer plusieurs clics de bouton.

1
répondu CChi 2013-02-08 23:29:37

Mon échantillon, testé dans Android studio 2.1

Définir le bouton dans la mise en page xml

<Button
    android:id="@+id/btn1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

Détection de pulsation Java

Button clickButton = (Button) findViewById(R.id.btn1);
if (clickButton != null) {
    clickButton.setOnClickListener( new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /***Do what you want with the click here***/
        }
    });
}
1
répondu Webserveis 2016-08-03 16:39:09

Pour faciliter les choses, vous pouvez utiliser la méthode lambda comme celle-ci pour enregistrer la mémoire des variables et éviter de naviguer de haut en bas dans votre classe view

//method 1
findViewById(R.id.buttonSend).setOnClickListener(v -> {
          // handle click
});

Mais si vous souhaitez appliquer l'événement click à votre bouton à la fois dans une méthode.

Vous pouvez utiliser la Question 3 de la réponse @ D. Tran. Mais n'oubliez pas d'implémenter votre classe view avec View.OnClickListener.

Dans d'autres pour utiliser la Question # 3 correctement

1
répondu Michael 2018-07-20 05:26:26

Question # 1 - Ce sont la seule façon de gérer les clics de vue.

Question # 2 -
Option#1/Option#4 - Il n'y a pas beaucoup de différence entre l'option 1 et l'option n ° 4. La seule différence que je vois est dans un cas l'activité implémente OnClickListener, alors que, dans l'autre cas, il y aurait une implémentation anonyme.

Option # 2-dans cette méthode, une classe anonyme sera générée. Cette méthode est un peu cumborsome, car vous devez le faire plusieurs fois, si vous avez plusieurs bouton. Pour les classes anonymes, vous devez faire attention à la gestion des fuites de mémoire.

Option # 3-cependant, c'est un moyen facile. Habituellement, les programmeurs essaient de ne pas utiliser de méthode jusqu'à ce qu'ils l'écrivent, et donc cette méthode n'est pas largement utilisée. Vous verriez surtout les gens utiliser L'Option # 4. Parce qu'il est plus propre en terme de code.

0
répondu Gaurav Arora 2013-02-08 23:29:24

Il existe également des options disponibles sous la forme de diverses bibliothèques qui peuvent rendre ce processus très familier aux personnes qui ont utilisé d'autres frameworks MVVM.

Https://developer.android.com/topic/libraries/data-binding/

Montre un exemple de bibliothèque officielle, qui vous permet de lier des boutons comme ceci:

<Button
    android:text="Start second activity"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:onClick="@{() -> presenter.showList()}"
/>
0
répondu Ryan The Leach 2018-06-04 01:55:43

Étape 1:Créer un Fichier XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/btnClickEvent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Click Me" />
</LinearLayout>

Étape 2:Créer MainActivity:

package com.scancode.acutesoft.telephonymanagerapp;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity implements View.OnClickListener {

    Button btnClickEvent;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnClickEvent = (Button) findViewById(R.id.btnClickEvent);
        btnClickEvent.setOnClickListener(MainActivity.this);

    }

    @Override
    public void onClick(View v) {
        //Your Logic
    }
}

HappyCoding!

0
répondu Manikanta Reddy 2018-07-20 15:57:16