IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Android Discussion :

Affecter un même comportement à plusieurs Togglebuttons


Sujet :

Android

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Homme Profil pro
    Autodidacte
    Inscrit en
    Décembre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Décembre 2015
    Messages : 8
    Par défaut Affecter un même comportement à plusieurs Togglebuttons
    Bonjour,
    Je suis en train de développer une petite application qui devrais me permettre d'animer un spectacle de théâtre d’improvisation.
    Je ne suis pas programmateur mais ai quelques notions et ça m’intéresse beaucoup d'apprendre. Du coup je me repose sur un manuel et fouille les forums mais là j'ai besoin de petits coups de pouces pour avancer un peu

    Voici le principe de mon appli:
    - Sur un écran figurent une liste de caractéristiques à attribuer à des joueurs. (des togglebuttons)
    - Pour l'instant le bouton change simplement de couleur lorsqu'on le sélectionne/désélectionne. A terme ce sera un peu plus riche mais allons y pas à pas.
    - Depuis le menu on accède à un mode d'édition qui permet non pas de changer la couleur mais le titre des boutons lorsqu'on clique dessus.

    En copiant du code à droite et à gauche j'ai réussi à faire quelque chose qui commence à fonctionner, mais je rencontre le problème suivant :

    - J'aimerais ne pas avoir à programmer chaque bouton indépendamment mais créer une classe anonyme (est ce que j'utilise les bons termes ???). J'ai trouvé des informations sur un site et je suis particulièrement intéressé par ce paragraphe.
    en fait on implémente des classes anonymes dans des attributs de façon à pouvoir les utiliser dans plusieurs éléments graphiques différents qui auront la même réaction pour le même évènement.
    Du coup j'ai codé selon l'exemple :

    Mainactivity
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    package giffres.imperco;
     
    import android.app.Fragment;
    import android.app.FragmentManager;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.CompoundButton;
    import android.widget.TextView;
    import android.widget.Toast;
    import android.widget.ToggleButton;
     
    //On déclare l'activité principale, dérivée d'AppacompatActivity et implémentant le Caraclistener du fragment
    public class MainActivity extends AppCompatActivity implements MyDialogFragment.CaracListener{
        //Déclaration des varaibles
        Boolean edit_mode = false;
        View targetView;
        MenuItem menuedit;
        ToggleButton psybutton1;
        ToggleButton psybutton2;
        ToggleButton phybutton1;
        ToggleButton phybutton2;
     
     
        private View.OnClickListener clickListenerBoutons = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //test du mode d'édition
                if (edit_mode) {
                    //Si mode d'édition,
                    //On cherche les fragments déja crées
                    FragmentManager manager = getFragmentManager();
                    Fragment frag = manager.findFragmentByTag("fragment_edit_carac");
     
                    //S'il y en a on les enlève
                    if (frag != null) {
                        manager.beginTransaction().remove(frag).commit();
                    }
     
                    //On ouvre le dialog d'édition de la caractéristique
                    MyDialogFragment EditCaracDialog = new MyDialogFragment();
                    EditCaracDialog.show(manager, "fragment_edit_carac");
     
                    //Si on n'est pas en mode d'édition
                    //Si le bouton est coché
                } else if (psybutton1.isChecked()) {
                    // on définit son image de fond
                    psybutton1.setBackgroundResource(R.drawable.button_red);
                    //Si le bouton n'est pas coché
                } else {
                    // on définit son image de fond
                    psybutton1.setBackgroundResource(R.drawable.button_grey);
                }
            }
        };
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //Affectation du fichier de layout
            setContentView(R.layout.activity_main);
     
            //Obtention des références des composants
            targetView = findViewById(R.id.MainLayout);
            psybutton1 = (ToggleButton) findViewById(R.id.button_psy1);
            phybutton1 = (ToggleButton) findViewById(R.id.button_phy1);
            psybutton2 = (ToggleButton) findViewById(R.id.button_psy2);
            phybutton2 = (ToggleButton) findViewById(R.id.button_phy2);
     
            //Comportement lors d'un changement d'un clic sur les boutons
            psybutton1.setOnClickListener(clickListenerBoutons);
            phybutton1.setOnClickListener(clickListenerBoutons);
            psybutton2.setOnClickListener(clickListenerBoutons);
            phybutton2.setOnClickListener(clickListenerBoutons);
        }
     
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate our menu from the resources by using the menu inflater.
            getMenuInflater().inflate(R.menu.main, menu);
            menuedit = menu.findItem(R.id.menu_edit);
            return true;
        }
     
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()) {
                case R.id.menu_load:
                    //Chargement d'une sauvegarde
                    return true;
                case R.id.menu_edit:
                    //Bascule mode d'édition
                    edit_mode = !edit_mode;
                    //Passage en mode d'édition ou non
                    EditMode();
                    return true;
                case R.id.menu_background:
                    // Choix de l'image de fond
                    return true;
                case R.id.menu_save:
                    // Sauvegarder la planche
                    return true;
            }
            return super.onOptionsItemSelected(item);
        }
     
        public void onFinishCaracDialog(String carac) {
            psybutton1.setTextOn(carac);
            psybutton1.setTextOff(carac);
        }
     
        public void EditMode(){
     
            if(edit_mode) {
                targetView.setBackgroundColor(R.color.white);
                menuedit.setTitle(R.string.menu_nedit);
                menuedit.setIcon(R.drawable.ic_done_black_24dp);
     
            }
            else {
                targetView.setBackgroundColor(R.color.black);
                menuedit.setTitle(R.string.menu_edit);
                menuedit.setIcon(R.drawable.ic_create_black_24dp);
            }
        }
     
    }
    et celui du fragment "Mydialogfragment"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    package giffres.imperco;
     
    import android.app.DialogFragment;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.KeyEvent;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.Window;
    import android.view.WindowManager;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.ToggleButton;
     
    /**
     * Created by david on 21/12/2015.
     */
    public class MyDialogFragment extends DialogFragment implements TextView.OnEditorActionListener {
        private EditText caractxt;
     
        public interface CaracListener {
            void onFinishCaracDialog(String carac);
        }
     
        // Empty constructor required for DialogFragment
        public MyDialogFragment() {
        }
     
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.carac_dialog, container);
            caractxt = (EditText) view.findViewById(R.id.caractxt);
     
            // set this instance as callback for editor action
            caractxt.setOnEditorActionListener(this);
            caractxt.requestFocus();
            getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
            getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
     
            return view;
        }
     
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            // Return input text to activity
            CaracListener activity = (CaracListener) getActivity();
            activity.onFinishCaracDialog(caractxt.getText().toString());
            this.dismiss();
            return true;
        }}
    Le début de l'opération se déroule normalement mais après avoir validé ma boite de dialogue, comme agir sur le bouton concerné et non sur un bouton désigné au préalable. Le problème se pose pour l'image de fond ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                    //Si on n'est pas en mode d'édition
                    //Si le bouton est coché
                } else if (psybutton1.isChecked()) {
                    // on définit son image de fond
                    psybutton1.setBackgroundResource(R.drawable.button_red);
                    //Si le bouton n'est pas coché
                } else {
                    // on définit son image de fond
                    psybutton1.setBackgroundResource(R.drawable.button_grey);
                }
    et pour le titre du bouton ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        public void onFinishCaracDialog(String carac) {
            psybutton1.setTextOn(carac);
            psybutton1.setTextOff(carac);
        }
    Quelqu'un peut-il me mettre sur la voie car là je commence à vraiment sécher et en plus j'ai l'impression que ce na doit pas être sorcier.

    J'ai aussi les quelques soucis suivants mais c'est secondaire, je recréerai des discussion exprès.
    Lors de l'utilisation:
    - Lorsque je modifie les titleon et titleoff de mon togglebutton, la mise à jour n'est effectué que lorsque je réédite ce bouton une seconde fois.
    - Lorsque je change d'orientation, le layout est réinitialisé et je perds tout mon paramétrage.
    - Lorsque je passe en mode d'édition, je demande normalement un background blanc mais j'obtiens un gris. Il doit y avoir un problème de transparence.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Malheureusement, je ne pense pas qu'il n'y ait beaucoup de programmateur ici
    Fin de la blague concernant ce paronyme.

    Je n'ai jamais fais d'Android, j'espère que les connaisseurs me reprendront si j'ai tord.
    Je fais le parallèle avec les listeners sous SWING pour construire cette réponse.

    en fait on implémente des classes anonymes dans des attributs de façon à pouvoir les utiliser dans plusieurs éléments graphiques différents qui auront la même réaction pour le même évènement.
    Tu peux stocker ton listener dans une variable, puis l'ajouter dans tes composants.
    Apparemment c'est ce que tu sembles faire, sauf que toi tu le stock dans un attribut.

    qu'entend tu par programmer chaque bouton indépendamment ?
    L'explication fournie en <quote> ne parle QUE de l'affectation des listeners selon ce que j'ai pu comprendre.

    Si par programmer "chaque bouton indépendamment", tu sous entend que c'est le code du listener qui est indépendant selon le bouton et que tu ne souhaites pas faire des vérification dans le listener pour savoir si machin.isChecked() alors je fais ci, sinon si truc.isChecked() alors je fais ça, il te faut des listeners indépendant. Il te faut un listener pour chaque bouton.

  3. #3
    Membre régulier
    Homme Profil pro
    Autodidacte
    Inscrit en
    Décembre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Décembre 2015
    Messages : 8
    Par défaut
    Hourra, j'ai compris.
    En fait, par "programmer indépendamment", je voulais simplement dire que lorsque je clique sur un bouton c'est lui qui devient rouge et non pas tous les boutons.
    Du coup, lors de l'appel de mon listener, je récupère simplement le togglebutton qui l'a déclenché puis je le stock dans une variable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        ToggleButton sourcebutton;
        private View.OnClickListener clickListenerBoutons = new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sourcebutton = (ToggleButton) v;
    Puis je réutilise cette variable dans le reste de mon code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    else if (sourcebutton.isChecked()) {
                    // on définit son image de fond
                    sourcebutton.setBackgroundResource(R.drawable.button_red);
                    //Si le bouton n'est pas coché
                } else {
                    // on définit son image de fond
                    sourcebutton.setBackgroundResource(R.drawable.button_grey);
                }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public void onFinishCaracDialog(String carac) {
            sourcebutton.setTextOff(carac);
            sourcebutton.setTextOn(carac);
            sourcebutton.setChecked(false);
        }
    En fait ce qu je n'avais pas compris, c'est que c'était l'argument view "v" qui représentait le bouton.
    Merci EyZox de d'être intéressé au sujet. Je ne suis pas sur que ce soit exactement ça que tu voyais, mais ça m'a mis sur la voie.

    Bon je passe à la suite alors à très bientôt

  4. #4
    Invité
    Invité(e)
    Par défaut
    Tu comprends sans comprendre, ou tu ne comprends qu'a moitié.
    Certes ce que tu as fais, ça fonctionne, mais c'est de la bidouille malpropre et c'est propice a la création de bug où a la prise de tête lors de la relecture de ton code.

    Pourquoi tu stocks ton listener dans un attribut de ta classe ? En as-tu besoin en dehors de ta fonction onCreate() ?
    Ici, tu rend accessible ta variable a toute ta classe. Si tu ne l'utilises que dans ta methode, le mieux est de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            //Affectation du fichier de layout
            setContentView(R.layout.activity_main);
     
            //Obtention des références des composants
            targetView = findViewById(R.id.MainLayout);
            psybutton1 = (ToggleButton) findViewById(R.id.button_psy1);
            phybutton1 = (ToggleButton) findViewById(R.id.button_phy1);
            psybutton2 = (ToggleButton) findViewById(R.id.button_psy2);
            phybutton2 = (ToggleButton) findViewById(R.id.button_phy2);
     
            final View.OnClickListener clickListenerBoutons = new View.OnClickListener() {
                /*Le code de ton listener */
            };
    
            //Comportement lors d'un changement d'un clic sur les boutons
            psybutton1.setOnClickListener(clickListenerBoutons);
            phybutton1.setOnClickListener(clickListenerBoutons);
            psybutton2.setOnClickListener(clickListenerBoutons);
            phybutton2.setOnClickListener(clickListenerBoutons);
        }
    et de supprimer ton attribut.

    Idem pour ton attribut ToggleButton sourcebutton si tu n'en as besoin que dans ton listenner, utilise une variable locale et supprime l'attribut. Ne donne pas accès a cet élément dans toute ta classe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
            @Override
            public void onClick(View v) {
                final ToggleButton sourcebutton = (ToggleButton) v;
                    /* La suite de tes traitements sur le sourcebutton */
                }

  5. #5
    Membre régulier
    Homme Profil pro
    Autodidacte
    Inscrit en
    Décembre 2015
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Autodidacte
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Décembre 2015
    Messages : 8
    Par défaut
    OK,
    Comme tu l'as compris j'y vais à tâtons et j'avais créé ce code d'après ce tuto:
    http://www.vogella.com/tutorials/And...s/article.html

    Donc j'ai essayé de faire sans attribut, en déclarant une variable dans la méthode Oncreate . (J'en ai aussi profité pour me renseigner sur la différence entre les deux.)
    Par contre, le retour de ma boite de dialogue de saisie des caractéristiques (un fragment) ne fonctionne plus. Et en effet ça semble normal puisque qu'il s'agit d'une méthode à part:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public void onFinishCaracDialog(String carac) {
            sourcebutton.setTextOff(carac);
            sourcebutton.setTextOn(carac);
            sourcebutton.setChecked(false);
        }
    Un peu naïvement j'ai essayé de placer cette méthode dans ma classe "oncreate" mais du coup c'est la paramètre carac qu'il ne reconnait pas.
    Bon je prends conscience que mon truc est carrément bordélique surtout avec cette histoire de fragment mais je n'ai pas trouvé de méthode simple pour faire autrement.

    Mon objectif de base était le suivant : ouvrir une boite de dialogue qui me permet de saisir un texte et affecter ce texte aux propriété TextOn et TextOff du bouton cliqué. Ça me semblait simple mais je me retrouve avec une usine à gaz (qui ne fonctionne d'ailleurs plus).

    Je mesure l'importance d'avoir un code propre et du coup je sais que ce n'est pas de l'énergie de perdue mais maintenant, il faut que je trouve une autre approche.

    En tous cas encore merci de m'avoir aidé.

    A+

  6. #6
    Invité
    Invité(e)
    Par défaut
    Dans ce cas la, tu ajoutes ton bouton en paramètre dans la signature de la méthode. (Sans oublier de modifier aussi la signature de ta méthode dans ton interface CaracListener)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2007] Affecter une même procédure à plusieurs controles d'un formulaire
    Par Jeannot45 dans le forum VBA Access
    Réponses: 8
    Dernier message: 29/06/2013, 09h14
  2. affecter la même liste d'élément à plusieurs Listbox
    Par elombre dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 29/05/2009, 08h24
  3. Réponses: 5
    Dernier message: 19/09/2007, 11h22
  4. Affecter la même valeur à plusieurs variables
    Par K20 dans le forum Langage
    Réponses: 7
    Dernier message: 03/01/2006, 23h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo