Android : le RelativeLayout, c’est bien !
Dans l'application qu'on développe au boulot, presque toute la mise en forme est faite à partie de LinearLayout...
Ca a un côté à la fois simple et pratique, car au final on retombe sur un système de boite relativement classique : on peut créer une boite qui est soit verticale, soit horizontale, et on peut mettre autant de widgets qu'on veut dedans... Du coup on n'a pas de mauvaise surprise quand on fait tourner l'application, c'est clair et facile à visualiser.
Seulement voilà, il a fallu que je fasse un "TreeView" (une vue arborescente, façon explorateur windows où on peut cliquer sur les croix pour ouvrir un groupe, le tout à l'infini...), et là, au-delà de 3-4 niveaux de profondeur, on explose la pile lors de l'affichage (lors des appels des méthodes "draw").
Et là en regardant de plus près le fonctionnement de notre TreeView, le problème ressort assez rapidement : chaque item est un LinearLayout horizontal, dans lequel on met à gauche une image (pour ouvrir/fermer), et à droite du texte et les éléments "fils". On a donc à droite un LinearLayout vertical avec en haut le texte, et en bas un autre LinearLayout vertical, qui contient tous les enfants... Et pour le fun, comme il a fallu mettre un numéro devant le texte, le texte s'est transformé en un LinearLayout horizontal avec des textes de chaque côté...
Je vous épargne le calcul, mais en gros dès qu'on descend un peu dans l'arbre, on se retrouve à avoir des dizaines de LinearLayouts imbriqués les uns dans les autres, et ça, c'est fortement déconseillé. Je ne sais pas trop en pratique comment le rendu est fait, mais il n'est pas impossible que pour chaque ViewGroup (et donc LinearLayout, qui en hérite) Android fasse un rendu, puis que ce rendu soit utilisé pour le rendu du ViewGroup suivant, etc... Sauf que si dans notre cas on a autant de micro-LinearLayouts de partout imbriqués, on fait effectivement rapidement une quantité énorme de rendus, largement de quoi exploser la limite de mémoire imposée par Android... Et puis indépendamment de ça, c'est mal d'imbriquer autant de layouts les uns dans les autres car ça met pas mal de stress sur la routine qui s'occupe de calculer récursivement la taille de tous les éléments à afficher...
Il existe en fait une solution simple, et finalement beaucoup plus lisible : le RelativeLayout. Dans ce layout, la règle est simple : on définit les positions des objets relativement à leurs voisins et au layout. Donc on va par exemple dire que l'image est collée en haut à gauche, tandis que le texte est collé en haut du layout, et se trouve à droite de l'image.
Ca marche super bien, c'est très efficace, et ça permet de remplacer tout un tas de LinearLayouts par un seul RelativeLayout. On aurait probablement pu utiliser un des autres layouts, comme le GridLayout, mais je ne voulais pas trop du côté super "tableau" de la chose... Avec le RelativeLayout, on fait globalement ce qu'on veut, du moment qu'on arrive à définir les relations entre les widgets.
Si ça vous intéresse, plus d'informations sont disponibles sur le site officiel d'Android, avec une très bonne explication de la différence entre LinearLayout et RelativeLayout.