Loupe

RecyclerView - questions courantes quand on a l'habitude (ou pas !) du Listview

Dans cet article, nous verrons une liste de questions fréquentes que l'on se pose en utilisant le RecyclerView. Aucune d'elle ne pourrait faire l'objet d'un article complet mais cela permet de trouver les réponses quelque part !

Pour rappel, cet article fait partie d'une série sur le composant RecyclerView d'Android :

  1. Optimiser l'affichage de vos listes en utilisant un RecyclerView
  2. Ajouter des sticky headers sur vos RecyclerView
  3. Ajouter des en-têtes repliables (collapsible headers) sur vos RecyclerView
  4. Créer des RecyclerView horizontaux, les fameux "horizontal RecyclerView"
  5. Comment créer un RecyclerView infini / endless ?
  6. Afficher une liste d'éléments en mode grille avec un RecyclerView
  7. Ajouter des swipes actions sur un RecyclerView vertical.
  8. Scroller via du code dans un RecyclerView vertical
  9. Cet article.
  10. Suspens.

Comment ajouter un en-tête de liste ?

Un en-tête de liste est facile à ajouter sur une Listview car il suffit d'appeler la méthode AddHeader

listView.AddHeaderView(headerView);

Il n'y a pas de mécanisme équivalent sur un RecyclerView mais il est facile de recréer ce comportement. (Une relecture de l'article initial de la série est peut être nécessaire)..

  1. On ajoute un type de vue "en-tête de liste".
  2. On retourne le nombre d'éléments à afficher plus un dans l'adapter.
  3. L'adapter retourne l'en-tête de liste lorsque l'on demande l'élément à la position 0 et l'élément à la position n-1 lorsqu'on demande l'élément à la position n.

Cela permet de créer des vues complètement différentes tout en bénéficiant des optimisations du RecyclerView. Par exemple :

Screenshot_2019-04-02-13-11-04-130_com.jonathanantoine.TVST.jpeg

Comment s'abonner au click sur un élément ?

Le click sur un élément n'est pas non plus pris en charge nativement par le RecyclerView. Il va donc falloir le faire vous même sur chacune des vues crées pour vos ViewHolders. On pensera à rendre la vue clickable via sa propriété clickable si nécessaire. Je fais cela dans le constructeur du ViewHolder :

public MonViewHolder(View view) 
    : base(view)
{
   view.Clickable = true;
   view.Click += (_, __) => Click();_forGrid = forGrid;
}

Comment ajouter du padding entre mes éléments ? 

La Listview expose un attribut dividerHeight bien pratique pour ajouter un espace entre chacun des éléments mais ce n'est pas le cas du RecyclerView. L'astuce ici consiste à utiliser un décorateur d'élément comme nous avons déjà pu le faire dans un précédent article de cette série.

Dans cette version du décorateur, nous allons surcharger la méthode GetItemOffsets pour lui indiquer que le décorateur doit influencer la position des éléments et faire un décalage de 8px en bas : 

public override void GetItemOffsets(
     Rect outRect, View view, RecyclerView parent, State state)
{
    base.GetItemOffsets(outRect, view, parent, state);
    outRect.Bottom = 8; // espace que l'on souhaite
}

Comment trouver les éléments actuellement affichés ?

Pour cela il faudra passer par le LayoutManager utilisé par le RecyclerView qui expose de manière générale les méthodes nécessaires. Le LinearLayoutManager (dont dérive le GridLayout manager utilisé dans un précédent article) expose par exemple ces méthodes :

  • int findFirstVisibleItemPosition() : retourne la position du premier élément visible.
  • int findFirstCompletelyVisibleItemPosition() : retourne la position du premier élément complètement visible.
  • int findLastVisibleItemPosition() : retourne la position du dernier élément visible.
  • int findLastCompletelyVisibleItemPosition() : retourne la position du dernier élément complètement visible.

 

Comment bloquer le scroll ?

Empêcher l'utilisateur de scroller peut être utile dans certains scenarii et c'est assez simple à mettre en place. Il va falloir créer votre propre LayoutManager (en dérivant de LinearLayoutManager ou GridLayoutManager par exemple) et surcharger les méthodes CanScrollHorizontally et CanScrollVertically :

internal class BlocableScrollLinearLayoutManager
   : LinearLayoutManager
{
    public BlocableScrollLinearLayoutManager(Context context)
     : base(context)
    {
    }

    public bool DisableScroll { get; set; }

    public override bool CanScrollVertically()
    {
        return !DisableScroll && base.CanScrollVertically();
    }
    
    public override bool CanScrollHorizontally()
    {
        return !DisableScroll && base.CanScrollHorizontally();
    }
}

 

Avez-vous d'autres blocages avec le RecyclerView ?

 

Happy coding :)

 

Photo de profil

Ces billets pourraient aussi vous intéresser

Vous nous direz ?!

Commentaires

comments powered by Disqus