getView appelé avec mauvaise position lors du défilement rapide
assez nouveau développeur Android ici.
J'ai rencontré un problème étrange que je ne suis pas sûr de savoir comment contourner. J'ai lu beaucoup de problèmes ici et qui sonnent comme ils sont le même problème que j'ai, mais que les solutions à leurs problèmes ne semblent pas applicables à ce qui se passe ici.
J'ai un custom listView mis en place en utilisant une classe séparée qui s'étend BaseAdapter et utilise un point de vue titulaire (j'ai mis cela en regardant les différents exemples de la coutume listviews). Il a un affichage de texte, un bouton, une barre de progression et un bouton image, et ces éléments sont cachés/modifié basé sur une AsyncTask utilisé pour télécharger un fichier.
Tout fonctionne bien quand je l'ai faites défiler la liste lentement. Quand j'ai faites défiler la liste rapidement en haut/en bas, c'est comme si le point de vue de certaines cellules dans la liste se ré-attribuée à d'autres cellules.
J'ai mis cette ligne dans le haut de mon "getView" de la méthode dans ma classe d'adaptateur:
@Override
public View getView(final int pos, View convertView, ViewGroup parent)
{
Log.i("ks3","getView called, position is " + pos);
J'ai 7 éléments dans ma liste, et 6 d'entre eux adapter à l'écran. Quand il obtient tout d'abord, je vois cela dans mon journal:
getView called, position is 0
getView called, position is 1
getView called, position is 2
getView called, position is 3
getView called, position is 4
getView called, position is 5
Quand je scroll vers le bas lentement jusqu'à l'élément suivant, c'est imprimé suivant:
getView called, position is 6
Quand j'ai défiler l'écran vers le haut, ce:
getView called, position is 0
Allant vers le bas et lentement produire ces résultats parfaitement.
Quand je commence à défiler en arrière rapidement, il affiche ce message d'un tas de fois, la plupart montrant 6 et 0 comme la position, mais de temps en temps je vais voir:
getView called, position is 1
getView called, position is 5
Les Positions 1 et 5 ne devrait pas être appelé, car ils sont toujours à l'écran. C'est comme si getView ai tout mélangé. Dans le même temps, comme je l'ai dit avant, ma liste a l'air étrange. Boutons Image sera déplacé vers le haut ou vers le bas une cellule où ils ne devraient pas l'être.
Si je retourne à défilement en douceur, je ne vois que des 0 et 6 pour la position de nouveau.
Honnêtement, je ne suis pas sûr de la façon de contourner ce problème. J'ai pensé que je pourrais peut-être limiter à quelle vitesse vous êtes en mesure de faire défiler la liste, mais n'ont pas été en mesure de trouver quelque chose qui fonctionne.
Merci!
Edit:
Je voulais mettre à jour un couple de choses à propos de cette question. La première étant que, à partir d'un commentaire ici et à partir de la vidéo de Google sur la liste, il est venu à mon attention que getView peut être appelé à d'autres choses, alors ce que j'ai imaginé qu'il était, telles que les mesures, et donc je ne devrais pas être alarmé par ce que j'ai pensé à l'origine, était une partie de mon problème (qui est que je pensais que getView a été appelé avec les mauvaises positions).
Deuxièmement, j'ai vu plusieurs fois que c'est une très mauvaise idée de "cache des vues à l'intérieur de votre carte." Je ne suis pas tout à fait clair sur ce que cela signifie, mais je suis sûr que c'est une des choses que je fais mal (j'ai enregistrer une instance d'un bouton, progressBar, imageButton...).
Qui, avec le fait que j'ai mise à jour de la vue sur l'extérieur de getView et je n'utilise pas notifyDataSetChanged(); ceux qui, ensemble, sont probablement à l'origine de certains déglingués des trucs à se produire.
Si vous ne trouvez pas toutes les erreurs dans votre code et et vous utiliser en Nid d'abeille ou au-dessus, vous pouvez essayer de désactiver l'accélération matérielle pour votre mise en forme de liste. L'accélération matérielle peut potentiellement causer de telles erreurs.
Il ne se sent comme un recyclage question. Je vais jeter un oeil à la vidéo de Google sur les listViews et de voir s'il y a des flagrants problèmes avec la façon dont je suis l'aide de la liste.
OriginalL'auteur Droidmon | 2012-03-15
Vous devez vous connecter pour publier un commentaire.
Il est exact que les
ListView
est la réutilisation de points de vue dans différents endroits de l'écran. C'est une optimisation pour garder la mémoire d'utilisation raisonnable et rapide par le pas de l'attribution de nouveaux points de vue de tous les temps.Les Chances sont que vous êtes à l'aide de
LiewView
de manière incorrecte. Regarder ce discours sur la façon de bien utiliserListView
pour obtenir toute l'histoire, mais voici les faits saillants:getView()
méthode ou vous obtiendrez un comportement étrange.getView(int, View, ViewGroup)
fournit une vue d'instance, de remplir ses champs au lieu de gonfler totalement nouveaux points de vue. En supposant que vous avez correctement mis en œuvregetItemType()
, vous aurez toujours le droitView
type de reproduction.getView()
méthode aussi vite que vous le pouvez, et ne faire que de soulever des poids lourds sur d'autres threads.getView()
ne veut pas forcément dire que les données seront affichées. Le cadre utilise à des fins de mesure. Étant donné que le travail pourrait être jetés, c'est une autre raison de s'assurer quegetView()
est aussi rapide que vous pouvez faire.notifyDataSetChanged()
. Ne pas jouer avec les points de vue directement, ils vous rempli sur la prochaine INTERFACE de boucle quand il fait redessiné.Juste après avoir passé quelques jours à retravailler un
ListView
qui a été mis en œuvre naïvement, je ressens votre douleur. Les résultats ont été à la hauteur, si!Sir pls se sentent ma douleur ! U peut pls Répondre à cette Question, stackoverflow.com/questions/22451081/...
J'ai des mi-lourds de traitement et d'ajouter de forme dynamique sur chaque article et je viens de trouver de la place pour que, dans getview(). donc, ce qui concerne votre point quand je peux le déplacer?
C'est comme le chargement d'une image dans ce cas. Vous ne voulez pas de décoder les images bitmap au cours de
getView()
. Afin de vous faire votre traitement sur un autre thread et de remplir un cache. LeListView
puis obtient finis les données de la mémoire cache ou montre un espace réservé si ce n'est pas encore prêt.tu veux dire que je doit exécuter asynctask dans ma carte? comment je dois gérer ce thread? où j'ai dû mettre que et où avait pour communiquer avec mon adaptateur éléments. dans getview() ou ..? merci
OriginalL'auteur Argyle
toujours utiliser cette approche dans getview:
convertView = inflater.inflate(R. layout.listinflate, parent, false);
Et laissez votre activité met en œuvre onScrollListener et lorsque l'utilisateur se jetant en informer votre listview adaptateur à jamais l'esprit en tenant des efforts pour mettre à jour les éléments correctement. et lorsque l'utilisateur n'est pas plus jetant dire l'adaptateur pour prendre soin de fournir les données dans getView.
Qui a résolu tous mes problèmes.
Et encore une chose, ne pas utiliser de wrap_content dans la vue de liste hauteur de. ensemble smoothscroll faux aussi.
OriginalL'auteur Shangab
j'ai eu le même problème: dans l'adaptateur, j'ai changé la couleur de fond dans la méthode getView mais parfois, la liste a été "reciclyng" points de vue (en se trompant de fond).
J'ai résolu tout simplement en mettant "autre chose" à chaque
if(...){changeBackground}
J'ai ajouté
else {restore default background}
Et puis il a travaillé en douceur
pas de problème! Heureux d'entendre cela! 😉
OriginalL'auteur Mark
getView
est appelée pour chaque élément de la liste qui doit être établi, mais il était auparavant pas visible à l'écran. Si vous faites défiler rapidement vous pourriez obtenir des positions étranges, mais qui ne devrait pas provoquer des erreurs comme vous le décrivez (je suppose que Android n'a pas d'erreur ici depuis ces ListViews sont assez bien testé). E. g. lorsque vous faites défiler assez vite, vous pourriez avoir 2 points de vue qui ont besoin d'obtenir attiré.Peut-être il ya quelque chose de mal dans votre code.
OriginalL'auteur zapl
Pour l'enregistrement et l'extension de la réponse de @Mark
Android fait la tâche suivante. Disons que j'ai une liste avec 100 éléments. Whem vous êtes chargement, getview est appelé l'élément 0,1,2,3... à 10 par exemple. Et si nous avons continué à nous, le prochain poste sera le 11. Cependant, la position 11 recycle le même point de vue que la position 0. Ainsi, la vue de la position de 11 existe, mais il a le tort de la valeur (la valeur 0).
Réponse: Modifier les données si la vue est null ou pas. Si la vue est nulle, alors dégonfler et de modifier les valeurs de la vue. Si non, la modification des valeurs de la vue.
Permet de dire que j'ai un item_view (mise en page) avec un seul textview, puis l'adaptateur doit être comme suit:
Droite version:
Mauvaise version:
OriginalL'auteur magallanes