Une approche alternative pour afficher la charge pendant la pagination

image

Travailler avec le chargement page par page dans les applications mobiles est un sujet assez simple et ne présente aucun écueil.

Le développeur est confronté à une tâche similaire assez souvent et, par conséquent, répéter encore et encore la même chose est ennuyeux et paresseux.

Mais n'importe quelle tâche, même la plus ordinaire, peut être résolue d'une autre manière, plus intéressante, pour acquérir de nouvelles connaissances et simplement étirer votre cerveau.

Pagination


En bref, tous les travaux sur la mise en œuvre de la pagination se composent des éléments énumérés ci-dessous:

  1. Ajouter l'écouteur à la vue du recycleur;
  2. Télécharger les données primaires;
  3. Prendre un rappel lorsque l'utilisateur fait défiler la liste;
  4. Afficher le téléchargement dans la liste après tous les éléments;
  5. Envoyez une demande de nouveaux articles;
  6. Affichez à nouveau les données.

Dans notre cas, le mécanisme de pagination de page a été implémenté, mais il n'y avait aucun affichage de la charge pendant que l'utilisateur faisait défiler la liste.

D'accord, faire cela une fois dans une application n'est pas un problème. S'il y a plusieurs écrans où cette fonctionnalité est nécessaire, vous pouvez écrire un adaptateur de base qui peut fonctionner avec un type de vue supplémentaire.

Mais que faire si la tâche est un peu plus compliquée?

Disons qu'il existe plusieurs projets pas nouveaux qui ont un module de base avec des fonctionnalités de base.

Étant donné que les projets sont loin de la première année, en conséquence, beaucoup de code hérité ont été accumulés liés à cette tâche, à savoir de nombreux adaptateurs avec différentes classes de base.

Comment puis-je résoudre le problème?


Créez un nouvel adaptateur de base qui pourra montrer la progression du téléchargement, réécrivez tous les anciens adaptateurs + écrans qui utilisent les adaptateurs, car vous devez contrôler l'état d'affichage de la charge sur chaque écran, dans chaque présentateur ou vue.

Cela peut prendre beaucoup de temps. De plus, une refactorisation importante peut entraîner un certain nombre de nouvelles erreurs, surtout si la couverture des tests dans les projets tend à zéro. De plus, une charge élevée sur le département QA avec des tests de régression de tous les écrans avec pagination pour plusieurs applications.

Ce serait formidable d'écrire un tel code qui nécessite un minimum de temps de la part du client de développement pour intégrer la solution de base dans sa fonctionnalité. Afin de ne pas avoir à implémenter la logique de contrôle de l'affichage de la progression du chargement - affichage et masquage.

À ce stade, j'ai pensé à utiliser la classe ItemDecoration .

Pourquoi ne pas utiliser cette classe pour encapsuler tout le travail lié à

  • déterminer quand afficher la charge et quand la cacher
  • progression du téléchargement du dessin

Malheureusement, aucune solution prête à l'emploi n'a été trouvée sur Internet - personne n'a essayé de la mettre en œuvre ou n'a tout simplement pas partagé son expérience après la mise en œuvre.

De quoi a-t-on besoin pour implémenter l'affichage de chargement pendant la pagination en utilisant ItemDecoration?


  • Retrait pour rendre la charge;
  • Comprendre la mise en œuvre de ItemDecoration lorsque nous devons montrer des progrès;
  • Dessiner le téléchargement;

Indentation


Tout développeur qui a créé SpacingItemDecoration au moins une fois sait comment mettre en retrait. La méthode ItemDecoration getItemOffsets nous aidera avec ceci:

override fun getItemOffsets(outRect: Rect, view: View, recyclerView: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, parent, state) } 

Pour tout élément de la liste, nous pouvons ajouter des retraits de chaque côté. Plus précisément, dans notre cas, nous devons comprendre que l'utilisateur a déroulé la liste jusqu'à la fin et au dernier élément en retrait du bas égal à la valeur de la future progression de téléchargement affichée + retraits de la progression elle-même.

Comment comprendre que la liste défile vers le bas?

Le code ci-dessous nous aidera avec ceci:

  private fun isLastItem(recyclerView: RecyclerView, view: View): Boolean { val lastItemPos = recyclerView.getChildAdapterPosition(view) return lastItemPos == recyclerView.adapter!!.itemCount - 1 } 

Au total, nous avons un code pour définir et implémenter l'indentation:

  override fun getItemOffsets(outRect: Rect, view: View, recyclerView: RecyclerView, state: RecyclerView.State) { super.getItemOffsets(outRect, view, recyclerView, state) when (isLastItem(recyclerView, view)) { true -> outRect.set(Rect(0, 0, 0, 120)) else -> outRect.set(Rect(0, 0, 0, 0)) } } private fun isLastItem(recyclerView: RecyclerView, view: View): Boolean { val lastItemPos = recyclerView.getChildAdapterPosition(view) return lastItemPos == recyclerView.adapter!!.itemCount - 1 } 

Un tiers du travail est fait!

Nous déterminons le temps d'affichage de la progression du téléchargement et appelons le rendu de la progression


La méthode ItemDecoration onDrawOver nous aidera avec ceci:

  override fun onDrawOver(canvas: Canvas, recyclerView: RecyclerView, state: RecyclerView.State) { super.onDrawOver(canvas, recyclerView, state) } 

La méthode onDrawOver ne diffère de la méthode onDraw que dans l'ordre de rendu. Les décorations OnDrawOver ne seront rendues qu'une fois l'élément de liste lui-même dessiné.

Dans la méthode onDrawOver, nous devons comprendre à quel moment nous devons dessiner la progression, à quel moment la supprimer et provoquer des mises à jour des éléments de la liste afin de masquer le retrait déjà en retrait.

Code de mise en œuvre des actions décrites ci-dessus:

  override fun onDrawOver(canvas: Canvas, recyclerView: RecyclerView, state: RecyclerView.State) { super.onDrawOver(canvas, recyclerView, state) when (showLoading(recyclerView)) { true -> { PaginationProgressDrawer.drawSpinner(recyclerView, canvas) isProgressVisible = true } else -> { if (isProgressVisible) { isProgressVisible = false recyclerView.invalidateItemDecorations() } } } } private fun showLoading(recyclerView: RecyclerView): Boolean { val manager = recyclerView.layoutManager as LinearLayoutManager val lastVisibleItemPos = manager.findLastCompletelyVisibleItemPosition() return lastVisibleItemPos != -1 && lastVisibleItemPos >= recyclerView.adapter!!.itemCount - 1 } 

Progression du dessin


Le code de rendu est assez volumineux et sera présenté dans un fichier séparé, un lien vers lequel je présenterai ci-dessous.

Je veux m'attarder uniquement sur les nuances nécessaires à la mise en œuvre.

Tous les travaux de dessin se font sur toile. En conséquence, il sera nécessaire de configurer une instance de l'objet Paint et de dessiner des arcs, indiquant les angles de début et de fin.

Une nuance importante est que pour rendre autant que possible similaire à une barre de progression standard, vous devez créer votre propre analogue d'interpolateur afin que l'animation de rendu se déroule de manière non linéaire.

Pour comprendre le travail des interpolateurs et comprendre ce que vous voulez obtenir de votre animation, je vous recommande de vous familiariser avec les graphiques qui décrivent le travail de différents types d'interpolateurs, par exemple, dans cet article

Références de code:

PaginationChargementDécoration
PaginationProgressDrawer

Si nécessaire, vous pouvez créer une interface ProgressDrawer et remplacer les implémentations dans PaginationLoadingDecoration.

Télécharger la vidéo de démonstration:


Merci d'avoir lu, profitez du codage :)

Source: https://habr.com/ru/post/fr468877/


All Articles