Aller au contenu

Double entrée dans une ListView


Fluckysan

Recommended Posts

Bonjour :)

J'ai un bug bizarre que je n'arrive pô à expliquer

J'ai une ListView classique avec un adapter classique mais des entrée qui sont en double

De plus, si je scroll tout en bas et que je reviens en haut de ma ListView, j'ai des entrée qui se rajoutent en premier (des doubles)

Quelqu'un a déjà eu cette étrangeté ?

Lien vers le commentaire
Partager sur d’autres sites

Bon j'avance un peu dans le débugage :o

La source de la ListView (ce que j'affiche) est bonne, c'est à dire qu'il n'y a pô d'entrée en double dedans

J'ai remarqué aussi que ces dédoublements surviennent uniquement quand ma ListView dépasse de l'écran, du coup les éléments qui sont dans la liste sont ceux qui sont visibles (et en double aussi)

Aucun soucis quand le nombre d'éléments fait que la liste ne dépasse pô de l'écran

Quelque chose à déclarer à propos du draw de la ListView ?

Lien vers le commentaire
Partager sur d’autres sites

Bon j'ai résolu temporairement le soucis en faisant du new à chaque getView

Temporairement parce que c'est moche et que du coup c'est pô fluide :o

Il faut que je vois pourquoi la View se répète lorsqu'elle existe déjà dans la ListView

Vous savez dans votre getView, vous avez 2 conditions, si la View existe ou si elle est nulle et il faut faire un new

J'ai pris cet exemple :

    public View getView(int position, View convertView, ViewGroup parent) {
       ItemView btv;

       if (convertView == null) {
           btv = new ItemView(this.mContext, this.mItemList.get(position));
     }else{
           btv = (ItemView) this.mItemList.get(position);
       }

       return btv;
   }

Bref quand j'affiche ma liste, je passe 4 fois dans la condition null (les 4 éléments affiché)

Puis lorsque je déroule, au lieu de passer à nouveau dans la condition null (puisque les éléments ont zamais étaient affichés donc en principe null) je me retrouve dans l'autre condition avec les éléments du débuts !

Or si je fais uniquement du new, ça fonctionne bien :o

Lien vers le commentaire
Partager sur d’autres sites

je fais uniquement du new. .où plutôt du inflateview pour être exact.

:mad: C'est pas bien ça! C'est à cause de choses comme ça qu'on retrouve des listes qui rament sous Android! Il faut REUTILISER au maximum (c'est un terminal mobile donc il faut pas trop le charger ... même sous l'iPhone on réutilise)

Lien vers le commentaire
Partager sur d’autres sites

popolbx a écrit:

je fais uniquement du new. .où plutôt du inflateview pour être exact.

 C'est pas bien ça! C'est à cause de choses comme ça qu'on retrouve des listes qui rament sous Android! Il faut REUTILISER au maximum (c'est un terminal mobile donc il faut pas trop le charger ... même sous l'iPhone on réutilise)

tu as un exemple à donner ?

--

Posté depuis BBFoC

Lien vers le commentaire
Partager sur d’autres sites

Où toi tu semble faire un truc du genre :

public View getView(int position, View convertView, ViewGroup parent) {
 View item = mInflater.inflate(R.layout.list_item_icon_text, null);

 ((TextView) item.findViewById(R.id.text)).setText(TEXTS[position]);
 ((ImageView) item.findViewById(R.id.icon)).setImageBitmap(BITMAPS[position]);

 return item;
}

Il faut au minimum faire :

public View getView(int position, View convertView, ViewGroup parent) {
 if (convertView == null) {
   convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
 }

 ((TextView) convertView.findViewById(R.id.text)).setText(TEXTS[position]);
 ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(BITMAPS[position]);

 return convertView;
}

Cela permet de réutiliser les cellules au lieu d'en créer des nouvelles (processus long en comparaison d'un changement de contenu). Si je dis "au minimum" c'est aussi parce qu'il est possible de faire mieux en stoquant à la création le couple (convertView.findViewById(R.id.text), convertView.findViewById(R.id.icon)) car ce sont des action qui sont effectuées à chaque fois qu'on fait un getView.

La réutilisation peut sembler inutile dans une optique de programmation objet mais c'est pourtant primordial pour avoir de longues listes "smooth". Dans le cas de petites listes (tellement petites qu'elle ne scrollent pas - elle sont entièrement visible à l'écran) ça ne sert à rien car il n'y a pas de réutilisation possible (aucune cellule ne "sort") mais il est toujours préférable de le faire car c'est une très bonne pratique et ça prépare la liste si cette dernière est amenée à s'agrandir :).

Modifié par Cyril Mottier
Lien vers le commentaire
Partager sur d’autres sites

Puisque tu me semble motivé pour faire en sorte d'avoir les listes les plus rapides possibles. Voilà le code qu'il faudrait pour encore optimiser. J'enregistre cette fois le couple dont je parle précédemment à chaque création de nouvelle cellule :

static class MyViewTag {
 TextView text;
 ImageView icon;
}

public View getView(int position, View convertView, ViewGroup parent) {
 MyViewTag tag;

 if (convertView == null) {
   convertView = mInflater.inflate(R.layout.list_item_icon_text, null);

   tag = new MyViewTag();
   tag = (TextView) convertView.findViewById(R.id.text);
   tag = (ImageView) convertView.findViewById(R.id.icon);

   convertView.setTag(tag);
 } else {
     tag = (MyViewTag) convertView.getTag();
 }

 tag.text.setText(TEXTS[position]);
 tag.icon.setImageBitmap(BITMAPS[position]);

 return convertView;
}

Amuse toi bien ;) ... je pense pas qu'il soit possible de faire en sorte que tes listes soient plus rapide qu'en utilisant cette méthode.

Modifié par Cyril Mottier
Lien vers le commentaire
Partager sur d’autres sites

t'as été un peu vite sur ton 2° exemple, tag n'est pas initialisé et remplacé par un holder dans le else. et TEXTS et BITMAPS je sais pas d'ou ça sors :/

quoiqu'il en sois j'ai testé le premier exemple qui est diablement efficace.

Dans KeepScren j ai la liste es applis installées sur le tel:

- avant : long à charger, lag en défilement

- après : un peu moins long à charger, plus de lags :D

ça me suffit

attention néanmoins à redéfinir toutes les propriétés des views de la convertView.

exemple j avais un :

if X {

text.setTextColor.....

}

du coup avec la convertView il faut faire

if(X){

text.setTextColor(...

}else{

text.setTextColor(couleur normale)

}

sinon ça devient assez drôle visuellement.

Lien vers le commentaire
Partager sur d’autres sites

t'as été un peu vite sur ton 2° exemple, tag n'est pas initialisé et remplacé par un holder dans le else. et TEXTS et BITMAPS je sais pas d'ou ça sors :/

Oups oui j'ai remplacé/corrigé. TEXTS et BITMAPS sont simplement des constantes (tableau de textes et de bitmaps) que j'ai créé juste pour mon exemple. Dans ton cas il faut utiliser tes données utilisées pour remplir la cellule.

Pour ce qui est de la couleur il faut bien penser à redonner exactement le même état à ta cellule bien sûr!

Essaie le second exemple et tu gagnera encore en performance ;)

Modifié par Cyril Mottier
Lien vers le commentaire
Partager sur d’autres sites

Bon courage les gars et n'hésitez pas à faire passer le mot.

Il faut bien garder à l'esprit que si une application Android rame, beaucoup de gens pense, à tort, qu'Android rame. Même si le problème vient de certains développeurs, c'est bien souvent Android dans son ensemble qui prend pour son grade :(

Je vais exagérer un peu mais l'avenir d'Android est sur VOS épaules : codez bien et propre, codez pour l'avenir d'Android!

Lien vers le commentaire
Partager sur d’autres sites

Rejoignez la conversation

Vous pouvez poster maintenant et vous enregistrez plus tard. Si vous avez un compte, connectez-vous maintenant pour poster.

Invité
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Répondre à ce sujet…

×   Collé en tant que texte enrichi.   Coller en tant que texte brut à la place

  Seulement 75 émoticônes maximum sont autorisées.

×   Votre lien a été automatiquement intégré.   Afficher plutôt comme un lien

×   Votre contenu précédent a été rétabli.   Vider l’éditeur

×   Vous ne pouvez pas directement coller des images. Envoyez-les depuis votre ordinateur ou insérez-les depuis une URL.

×
×
  • Créer...