Dot.Blog

C#, XAML, Xamarin, UWP/Android/iOS

Xamarin.Forms : Une ViewCell extensible

Changer la taille d’une ViewCell à la volée dans une liste peut permettre de rendre l’affichage plus compact tout en laissant la possibilité d’en voir plus. Mais ce comportement n’existe pas de base… Il faut un peu de code !

ViewCell extensible

On peut utiliser le procédé dans de nombreuses conditions. Partout où une partie de l’information n’est pas essentielle mais est suffisamment importante pour que l’utilisateur puisse avoir besoin de la voir s’il le désire. Un exemple tout simple pourrait être d’afficher la date et l’heure de réception d’un message dans une messagerie de type WhatsApp. Les bulles des messages sont toujours affichées mais un appui long sur une bulle permettrait de voir l’horodatage ou de le faire disparaître et ce non pas globalement mais pour chaque “bulle” en particulier.

Visuellement cela donnerait quelque chose comme la petite animation ci-dessous empruntée à Alex Dunn qui a déjà écrit sur ce besoin si courant mais si peu abordé il faut l’avouer :

expandingcell


Bref vous comprenez le principe.

Une fois une ViewCell affichée elle ne changera pas “comme ça” de taille, il va falloir l’aider un peu. Certes il faudra un binding sur la partie à rendre visible ou non, ce qui pourra se déclencher sur un appui long par exemple, mais cela n’existe pas out –of-the-box (nous verrons plus loin comment y arriver). Sans oublier le cœur du problème qui consiste à avoir une cellule capable de forcer son changement de taille à la volée car c’est bien là qu’est l’astuce du jour !

La Cellule extensible

Commençons par là. Il nous faut une cellule “extensible”, en réalité une cellule capable de forcer le calcul de sa taille même une fois affichée.

Le code est redoutablement simple :

public class ExpandingViewCell : ViewCell
{
    protected override void OnTapped()
    {
        base.OnTapped();
        ForceUpdateSize();
    }
}


Ce n’est pas très compliqué, le truc consistant à détourner le OnTapped() pour effectuer un ForceUpdateSize(). Sans oublier d’appeler en premier le traitement original (base) qui permet justement d’appeler le gestionnaire qui éventuellement basculera l’état de la partie cachée à visible (et l’inverse).

Il suffit donc d’utiliser ExpandingViewCell à la place d’une ViewCell et de gérer un champ du ViewModel booléen qui passe vrai/faux l’affichage de la partie additionnelle. Cette dernière sera bindée à cette propriété bien entendu.

Il est évident que la ListView utilisée devra être placée en mode HasUnevenRows=true.

Par défaut ici c’est sur le Tap du message qu’on devra accrocher une ICommand qui effectue la bascule de la propriété.

Le mieux serait d’avoir une gestion d’appui long, mais de base cette Gesture n’existe pas sous Xamarin.Forms.

Cela peut se faire assez facilement grâce aux “Effets” Xamarin.Forms qui n’ont rien à voir avec des “effets spéciaux” mais tout à voir avec la manipulation simplifiée de code natif…

Les effets XF sont plus simples à mettre en œuvre que l’injection de code natif ou le sous-classement, méthodes plus habituelles pour modifier le comportement d’un objet. Disons que le sous-classement ou l’écriture de nouveaux contrôles se justifient pleinement lorsque ce qu’on veut faire n’existe pas du tout. Les Effets sont eux plus simples à écrire s’il s’agit juste de prendre en charge une possibilité nativement supportée mais pas incluse dans le contrôle Xamarin.Forms correspondant.

Le LongPress est de ce type, cela existe sous Android et iOS, il suffit juste d’aller le chercher pour rajouter la Gesture à tout contrôle. Comme une sorte de Behavior.

Le même Alex Dunn à qui j’ai piqué l’animation a écrit un Effet de LongPress, alors il est justice de vous renvoyer sur son site pour y repiquer le code ! Vous verrez c’est assez simple.

Conclusion

Pouvoir changer la taille d’une cellule au runtime et une fois celle-ci déjà affichée s’avère extrêmement utile en moult occasions. Et comme nous l’avons vu on peut le faire avec une ou deux lignes de code en créant une ViewCell custom.

il existe mille contextes pour exploiter cette possibilité, certains n’auront besoin de rien de plus qu’un binding qui change de vrai à faux et réciproquement pour afficher ou cacher la partie supplémentaire, dans d’autres contextes il faudra peut-être ajouter quelque artifice comme la prise en compte d’une Gesture particulière, le LongPress étant celui auquel on pense en premier en général.

Grâce aux Effets Xamarin.Forms ajouter ce comportement n’est pas un problème, surtout en utilisant le code que je vous ai donné en lien.

Une chose : n’abusez pas du procédé… Les règles du design font qu’une App doit rester lisible pour l’utilisateur, les commandes cachées, les appuis longs non documentés etc peuvent rendre l’App confuse ou tout simplement en faire perdre l’intérêt pour ceux qui n’auront pas compris l’astuce et qui ne l’utiliseront pas…

Restez toujours sobre et lisible dans vos designs… et …

Stay Tuned !

blog comments powered by Disqus