web-dev-qa-db-fra.com

RecyclerView: recherche le dernier élément visible immédiatement après la création de la vue

J'ai un problème avec les méthodes suivantes:

int firstVisibleItemPosition = gridLayoutManager.findFirstVisibleItemPosition();
int lastVisibleItemPosition = gridLayoutManager.findLastVisibleItemPosition();

Mon objectif: enregistrer les données analytiques sur les éléments consultés par l'utilisateur.

Pour ce faire, j'appelle cette méthode dans deux scénarios différents:

  • à chaque fois, le défilement passait à l'état "inactif" et vérifiait quels étaient les éléments visibles. dans ce cas, je reçois les index attendus.

  • lorsque la RecyclerView devient "visible" pour l'utilisateur. C'est maintenant que le problème commence. Je m'attendrais à ce que lorsque le fragment contenant recylcerView soit passé à onResume(), l'appel de findLastVisibleItemPosition() renvoie les éléments visibles. mais il retourne -1, dans ce cas. Je suppose que cela a quelque chose à voir avec le chargement asynchrone de l'initialisation des éléments internes de l'adaptateur recyclerView + par rapport au cycle de vie du fragment/de l'activité. 

en reportant ce code de quelques millisecondes - findLastVisibleItemPosition() renvoie les bons index. mais je ne veux pas remettre à plus tard le codage dur à l'aide de handler + delay runnable, car la planification de runnable est une solution de rechange à ce que je veux vraiment faire: détecter à quel moment la vue du recycleur a fini de gonfler et d'afficher à l'écran toutes les vues possibles les pieds à l'intérieur de celui-ci ..

donc mes questions sont essentiellement:

  • comment puis-je détecter le moment où le RecyclerView a terminé l'initialisation/la mesure/le gonflage et le dessin des éléments enfants se trouvant à l'écran? (avant toute interaction utilisateur ..). 

  • existe-t-il un moyen fiable et conforme aux bonnes pratiques de savoir exactement quels éléments de la vue du recycleur sont réellement affichés à l'écran?

12
Tal Kanel

Qu'en est-il des changements de configuration? Si l'utilisateur change l'orientation de l'écran, les éléments visibles changeront également. En fait, les éléments visibles changent constamment en fonction de l'état de la RecyclerView, des données chargées, de la position de défilement et de la configuration actuelle de l'écran.

La meilleure chose à faire est probablement de créer une classe qui garde constamment la trace du sur-ensemble d'éléments visibles en l'imposant de mettre en œuvre l'interface ItemDecoration qui est appelée à chaque fois qu'une RecyclerView est redessinée à l'écran et que ce composant envoie des statistiques à intervalles réguliers. Vous le rattacheriez à la nouvelle instance RecyclerView lors du changement de configuration (en préservant son état).

Ainsi, par exemple, ce composant pourrait garder une trace des positions visibles minimales et maximales. Au début, ce sera -1 pour les deux. Ensuite, une fois les données chargées et les premiers éléments affichés à l'écran, la variable ItemDecoration sera rappelée. La première position d'élément visible sera 0 et la dernière position d'élément visible sera N. Après le défilement, les valeurs changent à nouveau. Vous ne garderiez que la valeur minimale de FirstVisibleItemPosition et la valeur maximale de LastVisibleItemPosition afin d'obtenir le sur-ensemble. Après X secondes sans modifications, ou si l'utilisateur revient de l'activité, vous enregistrez et envoyez ces numéros.

1
BladeCoder

Utilisez OnChildAttachListener pour détecter le moment où un recycleur associe un nouveau titulaire. Utilisez un mécanisme de délai pour envoyer les analitycs correctes (\ pas un délai codé en dur mais quelque chose comme ceci: 

...
public void run(){
  removeCallbacks()
  postDelay(sendAnalytics(correctInformation),25);
}

Le délai de 25 ms est plus fiable que l’attacher arbitrairement au onResume.

0
EE66