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 et sélection/clic


Sujet :

Composants graphiques Android

  1. #1
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Par défaut ListView et sélection/clic
    Bonjour à tous,

    Je continue mon apprentissage de l'API android, voici ce que j'aimerais faire : lorsqu'un item d'une ListView est cliqué/sélectionné, je voudrais changer sa couleur de fond (pour indiquer quel item de la liste est sélectionné). L'item garderait cette nouvelle couleur jusqu'à ce qu'un autre item soit cliqué/sélectionné...

    J'ai essayé plusieurs façons de faire, notamment en changeant le fond dans un AdapterView.OnItemClickListener, le problème est que lorsque l'adapteur recycle les vues (cf. le paramètre convertView de Adapter.getView), la vue avec le fond modifié réapparaît autre part dans la ListView.
    J'ai également essayé d'utiliser l'attribut android:listSelector, mais l'item ne change de couleur que pendant la durée du clic...

    Quelle est la solution à ce problème ?
    Merci !

  2. #2
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,
    J'ai essayé plusieurs façons de faire, notamment en changeant le fond dans un AdapterView
    Comment as tu fait ?

    Car je pense que en passant par l' inflater de ta view, tu dois avoir moyen de pouvoir changer les couleurs de fond comme tu veux , ou tu peux aussi passer par la procédure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public View getView(int position, View contentView, ViewGroup arg2)

  3. #3
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Par défaut
    Avec le OnItemClickListener j'avais teste comme ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    mListView.setOnItemClickListener(new ListView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            view.setBackgroundColor(Color.RED);
        }	
    });
    Le fond passe bien en rouge lors d'un clic, le probleme est que lorsque je fais defiler la liste, un autre item apparait en rouge a cause du recyclage de la View par l'adapteur...

  4. #4
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Essaye plutôt en créant toi même ton adapter ,

    http://developer.android.com/referen...w.ViewGroup%29

    Il te suffira pour cela de modifier ta vue obtenue en fonction de la position sélectionnée .

    Un exemple

    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
    public class TonAdapter extends ArrayAdapter {
     
         @Override
         public View getView(int position, View convertView, ViewGroup parent) {
             View view = convertView;
     
                if (view == null)
                {            
                    LayoutInflater li = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    //le layout représentant la ligne dans le listView
                    view = li.inflate(R.layout.list_view, null); 
                }         
     
               // maintenant tu peux travailler ta view qui correspond à une ligne 
              // si la ligne correspond à l'élément sélectionnée préalablement tu change son fond .
     
     
             return view;
     
         }
    }

  5. #5
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    156
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 156
    Par défaut
    Effectivement, c'est mieux en changeant le fond a partir de l'adapteur...Encore une fois merci Feanorin pour ton aide !

  6. #6
    Invité
    Invité(e)
    Par défaut
    j'ai un problèem un peu différent,

    Je voudrais changer la couleur de fond de ma listView mais à partir d'un bouton du menu que j'ai créer ... et je n'y arrive pas.

    Voici mon code :

    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
     
    public class ManagementAlarm extends Activity implements AlarmeAdapterListener{
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
            ArrayList<ListAlarme> listP = ListAlarme.getAListOfAlarms();
            AlarmeAdapter adapter = new AlarmeAdapter(this, listP);
            adapter.addListener(this); 
            ListView list = (ListView)findViewById(R.id.listalarme);
            list.setAdapter(adapter);   
        }
     
        public void onClick(ListAlarme item, int position) {
     
        	String idalr = ListAlarme.getAListOfAlarms().get(position).idAlarme;
        	String typealr = ListAlarme.getAListOfAlarms().get(position).typeAlarme;
        	int genrealr = ListAlarme.getAListOfAlarms().get(position).genre;
     
          	Intent intenalr1 = new Intent();
        	intenalr1.putExtra("id", idalr); 
        	intenalr1.putExtra("type", typealr); 
        	intenalr1.putExtra("genre", genrealr); 
        	intenalr1.putExtra("Position", position);
        	intenalr1.setClass(this, DetailAlarm.class);
    	    startActivity(intenalr1); 
       } 
     
        /**-----------------------------Barre de Menu----------------------------*/
     
        public boolean onCreateOptionsMenu(Menu menu) 
        {
           super.onCreateOptionsMenu(menu);
           MenuInflater inflater = new MenuInflater(this);
           inflater = getMenuInflater();
           inflater.inflate(R.menu.menu, menu);
           return true;
        }
         public boolean onOptionsItemSelected(MenuItem item) {
             switch (item.getItemId()) {
                 case R.id.ack:Toast.makeText(this, "Acknowledge this alarm", Toast.LENGTH_LONG).show();
                 //Mettre l'alarme choisi en gris
                                     break;
                 case R.id.ackall:Toast.makeText(this, "Acknowledge all alarms", Toast.LENGTH_LONG).show();
                 ((TextView)findViewById(R.id.alarme_id)).setBackgroundColor(Color.GRAY);
                 ((TextView)findViewById(R.id.alarme_type)).setBackgroundColor(Color.GRAY);            
                                     break;
                 case R.id.reset:Toast.makeText(this, "Reset this alarm", Toast.LENGTH_LONG).show();
                                     break;
                 case R.id.resetall:Toast.makeText(this, "Reset all alarms", Toast.LENGTH_LONG).show();             		
                 					 break;    
                 case R.id.update:Toast.makeText(this, " alarms update", Toast.LENGTH_LONG).show();          
                 					 break;             
             }
             return true;
         }
    }
    Je voudrais mettre cette action sur le bouton ackall de mon menu, mais les lignes de codes que j'ai mises fonctionnent uniquement sur la première ligne de ma listView, soit la ligne 0 passe en grise mais pas les autres, une idée de solution?

    j'ai essayé avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ((ListView)findViewById(R.id.listalarme)).setBackgroundColor(Color.GRAY);
    Mais ça ne change pas du tout la couleur.

    Merci

  7. #7
    Membre prolifique
    Avatar de Ryu2000
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2008
    Messages
    10 256
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2008
    Messages : 10 256
    Par défaut
    En fait peut être que la ListView change de background, met t'as tes items par dessus.
    Pour vérifier tu peux par exemple mettre qu'un item dans une ListView qui prend tout l'écran.
    Ou mieux, les layouts de tes items fait les transparentes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    android:background="@android:color/transparent"
    Peut être que là ça va changer de couleur.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Non ça n'a rien changé, enfin c'est toujours la 1ére ligne qui passe en gris
    (PS on s'est pas déja vu sur un autre forum ^^ de nouveau merci pour ton aide)

  9. #9
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,

    J'ai essayé avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ((ListView)findViewById(R.id.listalarme)).setBackgroundColor(Color.GRAY);
    Mais ça ne change pas du tout la couleur.
    Essaye de coller un invalidate sur ta liste après le changement de couleur.

    Je voudrais mettre cette action sur le bouton ackall de mon menu, mais les lignes de codes que j'ai mises fonctionnent uniquement sur la première ligne de ma listView, soit la ligne 0 passe en grise mais pas les autres, une idée de solution?
    plutôt que de changer la couleur de ton texte directement dans le menu , change juste une variable Color , puis met à jour dans l'adapter de ta listview qui affichera tes views avec la couleur contenu dans la variable Color .

  10. #10
    Invité
    Invité(e)
    Par défaut
    En fait je le vois si je met :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    android:background="#000000"
    mais il se trouver que la couleur de ma listView n'est pas déclaré dans mon xml mais dans une classe comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    if (mListA.get(position).genre == ListAlarme.grave) 
    		  {
    		    layoutItem.setBackgroundColor(Color.RED);
    		  } else 
    		  {
    		  	layoutItem.setBackgroundColor(Color.YELLOW);
    		  }
    C'est dans toute la ligne qui a la même couleur, et pas les item de la listView, et c'est toute la ligne que je veux repasser en gris lorsque je clique sur mon bouton. Une idée?

    En mettant les item transparents, j'ai quand même le tour des items (le reste de la listView) qui est soit rouge soit jaune selon le cas.

  11. #11
    Invité
    Invité(e)
    Par défaut
    @Feanorin

    Comment je met l'invalidate?

    et où je déclare ma variable Color, dans mon adapter, ou dans ma classe principale? vu que je déclare le background de ma listview(de départ) dans l'adapter il faut que je déclare ma variable à cette endroit la non?

  12. #12
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,
    Déjà première question a quel endroit est ce code (onCreate , onResume , ... )?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (mListA.get(position).genre == ListAlarme.grave) 
    		  {
    		    layoutItem.setBackgroundColor(Color.RED);
    		  } else 
    		  {
    		  	layoutItem.setBackgroundColor(Color.YELLOW);
    		  }
    Après ,
    Comment je met l'invalidate?
    La fonction invalidate te permet de demander à un composant de se redessiner (mettre à jour).
    Pour utiliser cette fonction rien de plus facile , il faut juste l'appeler après une modification comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    // Tu modifies ton composant soit ta liste 
    ListView liste = findViewById(R.id.listalarme);
    liste.setBackgroundColor(Color.GRAY);
    // tu lui demandes de se mettre à jour 
    liste.invalidate();
    A tester je ne sais pas si dans ton cas cela marche .
    NB : lorsque on modifie un élément graphiques essaye de le mettre en menbre de la classe cela t'éviteras de le rechercher à chaque coup vie les ressources.

    et où je déclare ma variable Color, dans mon adapter, ou dans ma classe principale? vu que je déclare le background de ma listview(de départ) dans l'adapter il faut que je déclare ma variable à cette endroit la non?
    Tu déclare ta variable dans ta classe principale. Maintenant si ton adapter est déclarer dans ton activity. Tu peux utiliser cette même variable, sinon il faut que tu crées une deuxième variable dans ton adapter que tu mets à jour depuis ton activity (ce qui est plus propre mais plus lourd au niveau du code ).
    Je parle toujours de ton exemple ou tu as essayer de modifier la couleur des éléments de ta liste et non la liste elle-même.

  13. #13
    Invité
    Invité(e)
    Par défaut
    Le bout de code en question se trouve dans une classe AlarmeAdapter qui extends BaseAdapter, et dans ma classe principale j'appelle cette classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        public void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
     
            ArrayList<ListAlarme> listP = ListAlarme.getAListOfAlarms();
            AlarmeAdapter adapter = new AlarmeAdapter(this, listP);
            adapter.addListener(this); 
            ListView list = (ListView)findViewById(R.id.listalarme);
            list.setAdapter(adapter);   
     
        }
    J'ai mis le code suivant sur le bouton de mon menu :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    ListView liste = (ListView)findViewById(R.id.listalarme);
                 liste.setBackgroundColor(Color.GRAY);
                 liste.invalidate();
    Mais ça ne change pas les couleurs (que ce soit les items ou la liste)

    Et pour répondre à ta derniére question, je veux changer la couleur soit des items, soit de la liste, ce qui est le plus simple à coder.

  14. #14
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Bonjour,

    J'ai testé vite fait chez moi et cela marche ! avec ou sans invalidate() pour le coup !

    J'avais pas vu mais si le bout de code se trouve dans le GetView de ton adapter alors pour le coup cela devient normal que le fond de la liste ne se modifie pas car tu l'écrases à chaque coup via ce bout de code !.

    Cela serait donc plutôt à cet endroit ou il faudrait que tu définisses la couleur de fond souhaité pour ta liste ?

    Mais j'ai du mal à comprendre pourquoi tu veux modifier entièrement le fond de ta liste si tu associes un fond par item en fonction d'une condition ?

  15. #15
    Invité
    Invité(e)
    Par défaut
    En fait j'ai une liste avec deux types d'alarmes, soit grave (afficher en rouge) soit juste des défauult (afficher en jaune).
    J'ai donc cette liste au départ, lorsque je lance mon appli

    J'ai un bouton (qui s'appelle ici ackall) qui permetter "d'acquitter toutes les alarmes", une fois les alarmes acquitter, pour montrer qu'elles le sont bien je veux qu'elles s'affichent en grises

    Peut-être qu'il faut que je déclare ailleur le fond de ma liste alors? mais si je le fait pas dans l'adapter, ni dans le xml, je le fais où?

  16. #16
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    J'ai un bouton (qui s'appelle ici ackall) qui permetter "d'acquitter toutes les alarmes", une fois les alarmes acquitter, pour montrer qu'elles le sont bien je veux qu'elles s'affichent en grises

    Peut-être qu'il faut que je déclare ailleur le fond de ma liste alors? mais si je le fait pas dans l'adapter, ni dans le xml, je le fais où?
    Non dans ce cas tu es bon , il faut juste que dans ton getView tu positionnes le background correspondant à ton item.

    Du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     // create a new  for each item referenced by the Adapter
    	        public View getView(int position, View convertView, ViewGroup parent) {
    	         	View v;
                            ListeItem item = mListA.get(position)
                            if (item.genre == ListAlarme.grave)
                                 // rouge
                                 v.setBackgroundColor(Color.RED);
                            else if (item.genre == ListAlarme.default)
                                 // rouge
                                 v.setBackgroundColor(Color.YELLOW);
                            else if (item.genre == ListAlarme.ackked)
                                 // rouge
                                 v.setBackgroundColor(Color.GRAY);
    C'est juste un exemple . On doit pouvoir faire mieux je pense .

  17. #17
    Invité
    Invité(e)
    Par défaut
    Ok je vois ce que tu veux dire, mais comment tester que je clique sur mon bouton ack qui est un bouton du menu dans cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     else if (item.genre == ListAlarme.ackked)
                                 // rouge
                                 v.setBackgroundColor(Color.GRAY);
    Parce que je ne test pas le "genre" de mon item, je veux tester si "j'appuie sur le bouton ack du menu"

    Et là je séche un peu pour savoir comment coder ça :s

  18. #18
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    J'ai un bouton (qui s'appelle ici ackall) qui permetter "d'acquitter toutes les alarmes", une fois les alarmes acquitter, pour montrer qu'elles le sont bien je veux qu'elles s'affichent en grises

    Parce que je ne test pas le "genre" de mon item, je veux tester si "j'appuie sur le bouton ack du menu"
    Je suis allez trop vite , dans ce cas créer une variable 'state' qui elle te précisera si l'utilisateur à appuyer l'acquittement du menu .
    Dans le getView :

    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
     
    public finale static  int ACKKED = 1;
    public finale static  int NO_ACKKED = 0;
    private int state;
     
    // dans le constructeur tu l'initialise à zéro
    state = NO_ACKKED;
     
    // Dans le menu 
    state = ACKKED;
     
    // create a new  for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
    	         	View v;
                            if (state = ACKKED) {
                                    v.setBackgroundColor(Color.GRAY);
                            } else {
                                    ListeItem item = mListA.get(position)
                                    if (item.genre == ListAlarme.grave)
                                        // rouge
                                       v.setBackgroundColor(Color.RED);
                                   else if (item.genre == ListAlarme.default)
                                       // jaune
                                      v.setBackgroundColor(Color.YELLOW);
                            }

  19. #19
    Invité
    Invité(e)
    Par défaut
    bon alors mauvaise nouvelles, aucune erreur dans le code mais ça ne marche, pour essayer de comprendre j'ai changer cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (ManagementAlarm.etat == ManagementAlarm.ACKKED )
    en cette ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (ManagementAlarm.etat == ManagementAlarm.NO_ACKKED )
    lorsque je lance mon appli, tous mes item ont un background gris, mais il ne se colore pas quand je clique sur mon bouton (ce que ça devrait faire en changeant cette ligne), c'est donc normal que dans l'autre sens ça ne marche pas non plus.

    je ne pouvais pas juste mettre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (etat == ACKKED)
    Eclipse me mettait une erreur.

  20. #20
    Expert confirmé

    Avatar de Feanorin
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    4 589
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 4 589
    Par défaut
    Rends public ta variable etat . et de revenir vers une condition du type

    Sinon tu peux toujours passer cette variable à ton adapter .

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [XL-2007] Listview éviter sélection par défaut
    Par danisoaz dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/08/2011, 10h47
  2. Listview problème sélection
    Par hugobosscool26 dans le forum C#
    Réponses: 2
    Dernier message: 21/09/2007, 11h59
  3. Listview et sélection
    Par Aleksis dans le forum C++Builder
    Réponses: 2
    Dernier message: 10/09/2006, 14h26
  4. [C#] Sélection clic droit TreeView
    Par fremsoi dans le forum Windows Forms
    Réponses: 4
    Dernier message: 16/01/2006, 23h37
  5. [débutant] Listview et double-clic
    Par Runlevel dans le forum C++Builder
    Réponses: 12
    Dernier message: 29/06/2004, 19h44

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