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

Composants graphiques Android Discussion :

ListView : ajout dynamique de row contenant des radiobutton


Sujet :

Composants graphiques Android

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut ListView : ajout dynamique de row contenant des radiobutton
    Bonjour tout l'monde !

    Je viens parmis vous avec le probleme suivant, j'essaie de créer une frame depuis laquelle on peut ajouter à l'aide d'un bouton de nouvelles vues contenant un radiogroup composé de plusieurs radiobuttons..

    Le soucis est qu'avec mon code, je me retrouve avec des comportement non désirés, par exemple :

    Lorsque j'ajoute plusieurs row, si la premiere je coche un des rabiobuttons, que je scrool en bas et qu'ensuite je scroll en haut de mon écran pour allez revoir ma premiere row...Mon radionbutton est décoché (donc soucis de recyclage de vue, alors que j'ai forcé la sauvegarde des données dans mon code)
    Et lorsque je coche un radiobutton et que j'ajoute de novuelles rows via le boutton dont j'ai parlé plus hat, à ce moment là certains radiobutton se cochent automatiquement.

    Voici mon code, pourriez vous me dire où se trouve mon erreur ?

    Un bout de mon frame :
    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
     
    		final ViewGroup root = (ViewGroup) inflater.inflate(
    				R.layout.slide_cavite, null);
    		listview_cavite = (ListView) root.findViewById(R.id.listview_cavite);
    		// Arbre.table_cavite.open();
     
    		adaptor = new Adaptor_cavite_item(root.getContext(),
    				R.layout.slide_item_cavite, Arbre.liste_cavite);
    		listview_cavite.setAdapter(adaptor);
    		ajouter_cavite = (Button) root.findViewById(R.id.ajouter_cavite);
    		ajouter_cavite.setOnClickListener(new OnClickListener() {
    			public void onClick(View v) {
    				//Arbre.liste_cavite.add(new Donnees_cavite());
    				adaptor.add(new Donnees_cavite(root.getContext()));
    				adaptor.notifyDataSetChanged();
    			}
    		});
    Les données de l'objet représenté dans une row :

    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
     
    public class Donnees_cavite {
     
     
    		    int rb_excrement_checked;
     
    		    public int get_rb_excrement_checked() {
    			return rb_excrement_checked;
    		    }
     
    		    public void setFirstChecked(int firstChecked) {
    			this.rb_excrement_checked = firstChecked;
    		    }
     
     
    		    public Donnees_cavite(Context context){
    		    	this.rb_excrement_checked = -1;
    		    }
     
    		}
    et enfin mon arrayadapter perso :

    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
     
     
    		public class Adaptor_cavite_item extends ArrayAdapter<Donnees_cavite> {
     
    			int layoutResourceId;
    			Holder holder;
    			ArrayList<Donnees_cavite> liste;
    			private LayoutInflater mInflater;
     
    			...
     
    			@Override
    			public View getView(final int position, View convertView, ViewGroup parent) {
    				View row = convertView;
     
     
    				if (row == null) {
     
    					row = mInflater.inflate(R.layout.slide_item_cavite, null);
     
    					holder = new Holder();
     
    					holder.excrement = (RadioGroup) row.findViewById(R.id.slide_cavite_excrement);
    					holder.excrement_1 = (RadioButton) row.findViewById(R.id.slide_cavite_excrement_rb1);
    					holder.excrement_2 = (RadioButton) row.findViewById(R.id.slide_cavite_excrement_rb2);
     
    					row.setTag(this.holder);
     
    				}else{
    					this.holder = (Holder) row.getTag();
    				}
     
     
    				holder.excrement.setOnCheckedChangeListener(new OnCheckedChangeListener() {
     
    					@Override
    					public void onCheckedChanged(RadioGroup arg0, int arg1) {
    						// TODO Auto-generated method stub
    						switch (arg1) {
    						case R.id.slide_cavite_excrement_rb1:
    							liste.get(position).setFirstChecked(1);
    							break;
     
    						case R.id.slide_cavite_excrement_rb2:
    							liste.get(position).setFirstChecked(2);
    							break;
    						}
    					}
    				});
     
     
    				if (liste.get(position).get_rb_excrement_checked() == 1){
    					holder.excrement_1.setChecked(true);
    					holder.excrement_2.setChecked(false);
    				}else if (liste.get(position).get_rb_excrement_checked() == 2){
    					holder.excrement_1.setChecked(false);
    					holder.excrement_2.setChecked(true);
    				}else{
    					holder.excrement_1.setChecked(false);
    					holder.excrement_2.setChecked(false);
    				}
     
    				return row;
     
    			}
     
    			static class Holder {
    				RadioGroup excrement;
    				RadioButton excrement_1,excrement_2; 
     
    				}
    			}
     
    		}


    Le pire, c'est que si je remplace ce bout de code à la fin de mon arrayadapter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    if (liste.get(position).get_rb_excrement_checked() == 1){
    					holder.excrement_1.setChecked(true);
    					holder.excrement_2.setChecked(false);
    				}else if (liste.get(position).get_rb_excrement_checked() == 2){
    					holder.excrement_1.setChecked(false);
    					holder.excrement_2.setChecked(true);
    				}else{
    					holder.excrement_1.setChecked(false);
    					holder.excrement_2.setChecked(false);
    				}
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (liste.get(position).get_rb_excrement_checked() == 1){
    					holder.excrement_1.setChecked(true);
    					holder.excrement_2.setChecked(false);
    				}else{
    					holder.excrement_1.setChecked(false);
    					holder.excrement_2.setChecked(true);
    				}
    Plus aucun comportement non désirable ! tout fonctionne nickel.. Déjà, je ne comprend pas pourquoi le code initial provoque mes "bugs" ^^ et ensuite, bah ce code marche..mais ça m'arrange pas car je dois avoir plusieurs radiobutton (>2) par row ^^

    Merci pour votre aide !

  2. #2
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Et si tu remplaces simplement par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    holder.excrement_1.setChecked(liste.get(position).get_rb_excrement_checked() == 1);
    holder.excrement_2.setChecked(liste.get(position).get_rb_excrement_checked() == 2);
    ?

    Ha oui... et aussi... faire un setOnCheckChangedListener(null) *avant* de modifier les setChecked(), et mettre la bonne valeur *apres*.... sinon, le listener sera appelé par setChecked() dans le getView()
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Oui c'est carrément plus propre le :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    holder.excrement_1.setChecked(liste.get(position).get_rb_excrement_checked() == 1);
    holder.excrement_2.setChecked(liste.get(position).get_rb_excrement_checked() == 2);
    ^^

    Je ne comprend pas très bien ce que tu as écrit à la suite par contre...estce que tu pourrait un peu plus détailler silteplait ?

    Le setCheck va appeler le listener (ce qui n'est pas bon si j'ai bien compris), donc je dois ajouter quelque part "avant" un "setOnCheckChangedListener(null)" c'est ça ? Mais..une mécanique doit m'échapper, je ne comprend pas très bien ce qu'est le problème et la solution que tu propose pour y remédier.

    En te remerciant

  4. #4
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Ben que tu as bien compris...

    Tu fais un appel à setChecked() après avoir mis le listener, ce qui veut dire que le listener risque d'être appelé pendant la "visualisation" de la donnée, et donc tu vas la modifier.

    Il vaut mieux faire l'inverse, et pour être sur (en cas de réutilisation de la view), qu'il n'y a pas un "vieux" listener attaché, il faut le mettre à null *avant* de faire le setChecked().

    Bon maintenant pas sur que cela résolve le problème.
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Hmm je comprend mieu la manipe...du coup j'ai modifié mon code comme suit :

    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
     
    public class Adaptor_cavite_item extends ArrayAdapter<Donnees_cavite> {
    	int layoutResourceId;
    	Holder holder;
    	ArrayList<Donnees_cavite> liste;
    	private LayoutInflater mInflater;
     
    	...
     
    	@Override
    	public View getView(final int position, View convertView, ViewGroup parent) {
    		View row = convertView;
     
    		if (row == null) {
    			row = mInflater.inflate(R.layout.slide_item_cavite, null);
    			holder = new Holder();
    			holder.excrement = (RadioGroup) row.findViewById(R.id.slide_cavite_excrement);
    			holder.excrement_1 = (RadioButton) row.findViewById(R.id.slide_cavite_excrement_rb1);
    			holder.excrement_2 = (RadioButton) row.findViewById(R.id.slide_cavite_excrement_rb2);
     
    			row.setTag(this.holder);
    		}else{
    			this.holder = (Holder) row.getTag();
    		}
     
    		holder.excrement.setOnCheckedChangeListener(null);
    		holder.excrement_1.setChecked(liste.get(position).get_rb_excrement_checked() == 1);
    		holder.excrement_2.setChecked(liste.get(position).get_rb_excrement_checked() == 2);
     
    		holder.excrement.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    			@Override
    			public void onCheckedChanged(RadioGroup arg0, int arg1) {
    				// TODO Auto-generated method stub
    				switch (arg1) {
    				case R.id.slide_cavite_excrement_rb1:
    					liste.get(position).setFirstChecked(1);
    					break;
    				case R.id.slide_cavite_excrement_rb2:
    					liste.get(position).setFirstChecked(2);
    					break;
    				}
    			}
    		});
    		return row;
    	}
     
    	static class Holder {
    		RadioGroup excrement;
    		RadioButton excrement_1,excrement_2; 
     
    		}
    	}
     
    }
    Mais j'ai toujours un problème lors du recyclage de vue...Concrètement voici ce qui se passe lorsque je lance l'appli :

    J'appuie plusieur fois sur le bouton qui permet d'ajouter de nouveau élément dans mon adapteur, donc je créé de nouveaux radiogroup.
    Je scroll au 20ième radiogroup (le dernier que je fais apparaitre), j'appui sur une des checkbox.
    J'appuie sur le boutton pour ajouter un radiogroup. Mon radiogroup '20' garde le bon radiobutton checked.
    Par contre, lorsque je scrol tout en haut (donc je retourne vers les premiers radiogroup) et que je rescrol vers le bas pour voir mon radiogroup '20'. A ce moment là le bouttun n'est plus coché...

    Je continuerai les tests/debug dans la soirée..

    edit: merci bien pour le coup de patte déjà en tout cas
    edit2 : bon...quelques tests plus tard, il s'averre que ma liste "globale" garde les valeur qui lui ont été affecté...Donc c'est pas un soucis de sauvegarde , mais de chargement de données sur la vue...je continue à creuser

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    107
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 107
    Points : 56
    Points
    56
    Par défaut
    Alors, j'ai pu résoudre mon soucis en m'inspirant du code qui se trouve dans la partie "12.2. Tutorial: Domain Model and Rows interaction" de cette page.
    Plus de problème de recyclage...Bon , je ne comprend pas pourquoi mon code plus haut ne fonctionne pas mais au moins, si quelqu'un galère..Le code de la page arrangé 'à notre sauce' permet de régler le problème.

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

Discussions similaires

  1. Ajout dynamique de fichiers selon des modèles prédéfinis
    Par Iori Yagami dans le forum Eclipse Modeling
    Réponses: 0
    Dernier message: 15/09/2013, 14h00
  2. Réponses: 2
    Dernier message: 23/05/2012, 19h56
  3. Réponses: 4
    Dernier message: 05/04/2010, 13h35
  4. Réponses: 1
    Dernier message: 11/09/2009, 12h03
  5. Ajouter un contrôle dynamique contenant des boutons
    Par koukoula dans le forum ASP.NET
    Réponses: 4
    Dernier message: 09/06/2008, 11h58

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