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 :

Éléments d'une ListView avec des couleurs de background différentes


Sujet :

Composants graphiques Android

  1. #1
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut Éléments d'une ListView avec des couleurs de background différentes
    Je sais que cette question a déjà été posée plusieurs fois mais aucune des réponses ne m'a permis de trouver une solution. Voilà le soucis : J'ai créé une ListView contenant environ 50 éléments. Certains de ces éléments ont une couleur de fond jaunes, d'autres blanche (de façon aléatoire). Pour faire ça, j'ai créé deux layouts, feed1.xml et feed2.xml :

    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
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:background="@color/yellow"
        >
        <ImageView
            android:id="@+id/ReadUnread"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:layout_toLeftOf="@+id/FeedItem"
            android:src="@drawable/readunread"
            android:background="@color/yellow"
        >
        </ImageView>
        <TextView 
            android:id="@+id/FeedItem"
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            android:padding="10dp" 
            android:textSize="12sp" 
            android:textColor="#000"
            android:textStyle="bold" 
            android:background="@color/yellow">
        </TextView>
    </LinearLayout>
    Le second layout est exactement le même que celui-ci si ce n'est "@color/yellow" qui est remplacé par "@color/white".

    Le code qui crée la ListView ressemble à ça (c'est une version allégée évidemment) :

    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
    public class ItemsListActivity extends ListActivity implements Runnable {
     
        static final int FEED_RESULT = 0;
        private ArrayList<Feed> feeds;
        private FeedAdapter m_feedAdapter;
        public ListView lv;
     
        private Handler handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                createListAdapter();
            }
        };
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }
     
        public void createListAdapter()
        {
            m_feedAdapter = new FeedAdapter(this, R.layout.feed, feeds);
            setListAdapter(m_feedAdapter);
     
            lv = getListView();
            lv.setTextFilterEnabled(true);
            lv.setCacheColorHint(0);
            lv.setDividerHeight(2);
            lv.setScrollingCacheEnabled(false);
     
     
            lv.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view,
                        int position, long id) {
                    Intent intent = new Intent(ItemsListActivity.this,
                                ReaderActivity.class);
                    Bundle bundle = new Bundle();
                    bundle.putInt("id", feeds.get(position).getId());
                    intent.putExtras(bundle);
                    startActivityForResult(intent, FEED_RESULT);
                }
            });
        }
     
        @Override
        public void run() {
            Bundle bundle = this.getIntent().getExtras();
            handler.sendEmptyMessage(0);
        }
     
        private Boolean getFeeds() {
            feeds = new ArrayList<Feed>();
        }
     
        private class FeedAdapter extends ArrayAdapter<Feed> {
     
            private ArrayList<Feed> feeds;
     
            public FeedAdapter(Context context, int textViewResourceId,
                    ArrayList<Feed> feeds) {
                super(context, textViewResourceId, feeds);
                this.feeds = feeds;
            }
     
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                Feed f = feeds.get(position);
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    if (f.getWhite() == 0)
                        v = vi.inflate(R.layout.feed1, null);
                    else
                        v = vi.inflate(R.layout.feed2, null);
                }
                if (f != null) {
                    TextView tt = (TextView) v.findViewById(R.id.FeedItem);
                    ImageView im = (ImageView) v.findViewById(R.id.ReadUnread);
                    if (tt != null) {
                        tt.setText(Html.fromHtml("<b>"+f.getSubject()+"</b>"+"<small> >>"+f.getAuthor()+"</small>"));
                        tt.setTag(f.getId());
                    }
                }
                return v;
            }
        }
    }
    Quand je lance l'application, que ce soit sur l'émulateur ou sur un appareil Android, tout semble bon jusqu'à ce que je scroll dans la liste. À ce moment là, les couleurs de fonds changent de manière complètement aléatoire. Des éléments "jaunes" deviennent "blancs"*et inversement sans qu'il y ait de logique particulière... J'ai essayé pas mal de choses, notamment avec setCacheColorHint() ou setScrollingCacheEnabled() mais sans succès.

    Avez-vous une idée de ce qui pourrait causer ce bug d'affichage?

    Merci

    PS : L'application utilise Android 1.6.

  2. #2
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    Le ListView réutilise les composants pour afficher les éléments suivants via "convertView", mais tu ne peux pas en déterminer l'ordre.

    Ainsi par exemple pour un composant "jaune" tu peux recevoir un "convertView" qui a été initialisé sur un composant "blanc"...

    Au début tout va bien car la ListView semble créé autant de composant qu'il y a d'élément visible... mais dès que tu scrolles les éléments invisibles sont "recycler" pour les nouveaux éléments, et donc tu n'as plus de moyen de manipuler la couleur.



    Il serait préférable d'utiliser un seul layout, et de spécifier explicitement la couleur à chaque fois via un setBackgroundColor() sur ton composant.


    a++

  3. #3
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    Ok! Je vois l'idée. Mais j'ai en revanche toujours le même problème. J'ai changé ma fonction getView() de cette manière :

    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
     
     @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                Feed f = feeds.get(position);
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.feed1, null);
                }
                if (f != null) {
                    TextView tt = (TextView) v.findViewById(R.id.FeedItem);
                    ImageView im = (ImageView) v.findViewById(R.id.ReadUnread);
                    if (tt != null) {
                        tt.setText(Html.fromHtml("<b>"+f.getSubject()+"</b>"+"<small> >>"+f.getAuthor()+"</small>"));
                        tt.setTag(f.getId());
                        if (f.getUnread() == 0) {
    						im.setBackgroundColor(R.color.white);
    						tt.setBackgroundColor(R.color.white);	
                        }
                    }
                }
                return v;
            }

  4. #4
    Rédacteur
    Avatar de MrDuChnok
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2002
    Messages
    2 112
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 112
    Points : 4 240
    Points
    4 240
    Par défaut
    Et comme ça :
    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
     
     @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                Feed f = feeds.get(position);
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.feed1, null);
                }
                if (f != null) {
                    TextView tt = (TextView) v.findViewById(R.id.FeedItem);
                    ImageView im = (ImageView) v.findViewById(R.id.ReadUnread);
                    if (tt != null) {
                        tt.setText(Html.fromHtml("<b>"+f.getSubject()+"</b>"+"<small> >>"+f.getAuthor()+"</small>"));
                        tt.setTag(f.getId());
                        if (f.getUnread() == 0) {
    						im.setBackgroundColor(R.color.white);
    						tt.setBackgroundColor(R.color.white);	
                        } else {
    						im.setBackgroundColor(R.color.yellow);
    						tt.setBackgroundColor(R.color.yellow);
                        }
                    }
                }
                return v;
            }
    ?
    Si vous jugez mon post utile dans la résolution de votre problème, n'hésitez pas à utiliser le système de vote afin d'améliorer la qualité du forum

  5. #5
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    +1

    Tu ne dois pas changer les valeurs quand bon te semble, mais dans tous les cas.

    Lorsque tu reçois une View dans getView(), tu ne sais pas comment elle était affiché dans la cellule précédente, donc tu dois tout réinitialiser.


    a++

  6. #6
    Membre habitué

    Profil pro
    Inscrit en
    Mars 2004
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Mars 2004
    Messages : 126
    Points : 129
    Points
    129
    Par défaut
    Wouhou \o/

    Pour moi, comme le jaune est la couleur par défaut d'un item, je ne pensais pas nécessaire de le re-spécifier dans le getView(). Du coup, ça marche parfaitement bien!

    Merci

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    En fait il faut se dire qu'il n'y a pas de valeur par défaut.
    Ou plutôt les seules valeurs par défaut sont celles définit dans le layout et qui ne change jamais.

    Dès que tu changes un élément dans getView(), il faut le "changer" pour toutes les cellules.


    a++

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

Discussions similaires

  1. Simuler une listbox avec des couleurs
    Par Invité dans le forum Contribuez
    Réponses: 9
    Dernier message: 19/03/2020, 20h49
  2. Réponses: 3
    Dernier message: 28/10/2012, 09h59
  3. Réponses: 13
    Dernier message: 30/05/2012, 10h42
  4. "sectionner" une courbe avec des couleurs
    Par Angel30 dans le forum Interfaces Graphiques
    Réponses: 3
    Dernier message: 26/05/2009, 16h43

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