J'ai un RecyclerView qui charge certaines données de l'API, comprend une URL d'image et des données, et j'utilise networkImageView pour charger l'image paresseux.
@Override
public void onResponse(List<Item> response) {
mItems.clear();
for (Item item : response) {
mItems.add(item);
}
mAdapter.notifyDataSetChanged();
mSwipeRefreshLayout.setRefreshing(false);
}
Voici l'implémentation pour Adapter:
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, final int position) {
if (isHeader(position)) {
return;
}
// - get element from your dataset at this position
// - replace the contents of the view with that element
MyViewHolder holder = (MyViewHolder) viewHolder;
final Item item = mItems.get(position - 1); // Subtract 1 for header
holder.title.setText(item.getTitle());
holder.image.setImageUrl(item.getImg_url(), VolleyClient.getInstance(mCtx).getImageLoader());
holder.image.setErrorImageResId(android.R.drawable.ic_dialog_alert);
holder.origin.setText(item.getOrigin());
}
Le problème est que lorsque nous avons une actualisation dans recyclerView, cela clignote pendant très peu de temps au début, ce qui semble étrange.
Je viens d'utiliser GridView / ListView à la place et cela a fonctionné comme prévu. Il n'y avait aucun blincking.
configuration pour RecycleView dans onViewCreated of my Fragment
:
mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
mGridLayoutManager = (GridLayoutManager) mRecyclerView.getLayoutManager();
mGridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return mAdapter.isHeader(position) ? mGridLayoutManager.getSpanCount() : 1;
}
});
mRecyclerView.setAdapter(mAdapter);
Quelqu'un confronté à un tel problème? Quelle pourrait être la raison?
Réponses:
Essayez d'utiliser des ID stables dans votre RecyclerView.
setHasStableIds(true)
et remplacergetItemId(int position)
.Sans ID stables, après
notifyDataSetChanged()
, les ViewHolders sont généralement affectés à des positions différentes. C'était la raison de cligner des yeux dans mon cas.Vous pouvez trouver une bonne explication ici.
la source
Selon cette page de problème ... il s'agit de l'animation de changement d'élément de recycleview par défaut ... Vous pouvez la désactiver ... essayez ceci
Changement dans la dernière version
Cité du blog des développeurs Android :
la source
Cela a simplement fonctionné:
la source
code
ItemAnimator animator = recyclerView.getItemAnimator (); if (instance d'animation de SimpleItemAnimator) {((SimpleItemAnimator) animateur) .setSupportsChangeAnimations (false); }code
J'ai le même problème de chargement d'image à partir de certaines URL, puis imageView clignote. Résolu en utilisant
au lieu de
ce qui évite de recharger ces anciennes données inchangées.
la source
essayez ceci pour désactiver l'animation par défaut
c'est la nouvelle façon de désactiver l'animation depuis le support Android 23
cette ancienne méthode fonctionnera pour l'ancienne version de la bibliothèque de support
la source
En supposant que
mItems
la collection qui soutient votreAdapter
, pourquoi supprimez-vous tout et rajoutez-vous? Vous lui dites essentiellement que tout a changé, donc RecyclerView relie toutes les vues que je suppose que la bibliothèque d'images ne la gère pas correctement où elle réinitialise toujours la vue même s'il s'agit de la même URL d'image. Peut-être qu'ils avaient une solution intégrée pour AdapterView afin que cela fonctionne correctement dans GridView.Au lieu d'appeler,
notifyDataSetChanged
ce qui entraînera la ré-liaison de toutes les vues, appelez les événements de notification granulaire (notification ajoutée / supprimée / déplacée / mise à jour) afin que RecyclerView ne relie que les vues nécessaires et que rien ne clignote.la source
Recyclerview utilise DefaultItemAnimator comme animateur par défaut. Comme vous pouvez le voir dans le code ci-dessous, ils modifient l'alpha du support de vue lors du changement d'élément:
Je voulais conserver le reste des animations mais supprimer le "scintillement" alors j'ai cloné DefaultItemAnimator et supprimé les 3 lignes alpha ci-dessus.
Pour utiliser le nouvel animateur, appelez simplement setItemAnimator () sur votre RecyclerView:
la source
Dans Kotlin, vous pouvez utiliser une `` extension de classe '' pour RecyclerView:
la source
Hé @Ali, ça pourrait être une relecture tardive. J'ai également rencontré ce problème et résolu avec la solution ci-dessous, cela peut vous aider à vérifier.
La classe LruBitmapCache.java est créée pour obtenir la taille du cache d'image
La classe de singleton VolleyClient.java [ extend Application] a été ajoutée sous le code
dans le constructeur de classe singleton VolleyClient, ajoutez ci-dessous l'extrait de code pour initialiser ImageLoader
J'ai créé la méthode getLruBitmapCache () pour renvoyer LruBitmapCache
J'espère que ça va vous aider.
la source
pour moi
recyclerView.setHasFixedSize(true);
travailléla source
Dans mon cas, ni l'un ni l'autre des éléments ci-dessus ni les réponses d'autres questions de stackoverflow ayant les mêmes problèmes n'ont fonctionné.
Eh bien, j'utilisais une animation personnalisée chaque fois que l'on cliquait sur l'élément, pour lequel j'appelais notifyItemChanged (position int, charge utile de l'objet) pour transmettre la charge utile à ma classe CustomAnimator.
Remarquez qu'il existe 2 méthodes onBindViewHolder (...) disponibles dans l'adaptateur RecyclerView. La méthode onBindViewHolder (...) ayant 3 paramètres sera toujours appelée avant la méthode onBindViewHolder (...) ayant 2 paramètres.
Généralement, nous remplaçons toujours la méthode onBindViewHolder (...) ayant 2 paramètres et la principale racine du problème était que je faisais la même chose, car chaque fois que notifyItemChanged (...) est appelé, notre méthode onBindViewHolder (...) être appelé, dans lequel je chargeais mon image dans ImageView en utilisant Picasso, et c'était la raison pour laquelle il se chargeait à nouveau indépendamment de sa mémoire ou d'Internet. Jusqu'à ce qu'il soit chargé, il me montrait l'image de l'espace réservé, ce qui était la raison pour laquelle je clignotais pendant 1 seconde chaque fois que je cliquais sur la vue de l'élément.
Plus tard, je remplace également une autre méthode onBindViewHolder (...) ayant 3 paramètres. Ici, je vérifie si la liste des charges utiles est vide, puis je renvoie l'implémentation de la super classe de cette méthode, sinon s'il y a des charges utiles, je mets simplement la valeur alpha de l'itemView du support à 1.
Et oui, j'ai eu la solution à mon problème après avoir malheureusement perdu une journée complète!
Voici mon code pour les méthodes onBindViewHolder (...):
onBindViewHolder (...) avec 2 paramètres:
onBindViewHolder (...) avec 3 paramètres:
Voici le code de la méthode que j'appelais dans onClickListener de l'itemView de viewHolder dans onCreateViewHolder (...):
Remarque: vous pouvez obtenir cette position en appelant la méthode getAdapterPosition () de votre viewHolder à partir de onCreateViewHolder (...).
J'ai également remplacé la méthode getItemId (int position) comme suit:
et
setHasStableIds(true);
j'ai appelé mon objet adaptateur en activité.J'espère que cela aidera si aucune des réponses ci-dessus ne fonctionne!
la source
Dans mon cas, il y avait un problème beaucoup plus simple, mais il peut ressembler beaucoup au problème ci-dessus. J'avais converti un ExpandableListView en un RecylerView avec Groupie (en utilisant la fonctionnalité ExpandableGroup de Groupie). Ma mise en page initiale avait une section comme celle-ci:
Avec layout_height réglé sur "wrap_content", l'animation du groupe développé au groupe réduit semblait clignoter, mais c'était en réalité une animation à partir de la "mauvaise" position (même après avoir essayé la plupart des recommandations de ce fil).
Quoi qu'il en soit, changer simplement layout_height en match_parent comme ceci a résolu le problème.
la source
J'ai eu un problème similaire et cela a fonctionné pour moi Vous pouvez appeler cette méthode pour définir la taille du cache d'image
la source
pour mon application, certaines données ont été modifiées mais je ne voulais pas que la vue entière clignote.
Je l'ai résolu en atténuant uniquement l'ancienne vue vers le bas de 0,5 alpha et en commençant la newview alpha à 0,5. Cela a créé une transition de fondu plus douce sans faire disparaître complètement la vue.
Malheureusement, à cause d'implémentations privées, je ne pouvais pas sous-classer le DefaultItemAnimator pour effectuer cette modification, j'ai donc dû cloner le code et apporter les modifications suivantes
dans animateChange:
dans animateChangeImpl:
la source
L'utilisation de méthodes de recyclage appropriées pour mettre à jour les vues résoudra ce problème
Commencez par apporter des modifications à la liste
Puis notifiez en utilisant
J'espère que cela aidera !!
la source
Essayez d'utiliser le stableId dans la vue du recycleur. L'article suivant l'explique brièvement
https://medium.com/@hanru.yeh/recyclerviews-views-are-blinking-when-notifydatasetchanged-c7b76d5149a2
la source
Solution Kotlin:
la source