Greg's Devblog Par un développeur, pour les développeurs

6jan/116

Android 3.0 enfin présenté !

Ca fait longtemps qu'on l'attendait, à tel point qu'hier au boulot on se disant ne pas comprendre la stratégie de Google sur Android, avec un système pas du tout adapté aux tablettes et une relative opacité dans le développement (pour un projet OpenSource).

Et bien voilà, ce matin est arrivée une belle vidéo illustrant ce que sera Android 3.0 (Honeycomb), et je dois avouer que contrairement à ce que je pensais, je ne suis pas déçu, bien au contraire ! Les fameuses 4 touches d'Android (parfois 3), à savoir Back, Menu, Home, et Search ne seront effectivement plus obligatoires, car intégrées directement dans l'interface. L'iPad n'a qu'à se tenir !

Sans plus attendre, je vous laisse découvrir la vidéo :

Et vous, vous en pensez quoi ?

Via googlesystem.blogspot.com

11nov/100

Android : remplacer AbsoluteLayout par RelativeLayout

Sur Android, Google avait prévu un AbsoluteLayout, dont le principe est relativement simple : on peut placer un View où on veut dessus, en pixels. Ce layout a cependant été déprécié pour des soucis de compatibilité des applications : si une application fait tous ses placements en pixels, le jour où on la met sur un écran de résolution différente, c'est pourri !

Sur les différents sites, quand on voit des gens demander ce qu'on peut utiliser pour remplacer l'AbsoluteLayout, pas mal de personnes crient en scandale en disant que si ce layout a été retiré c'est justement parce que placer des choses au pixel près c'est mal, et qu'il faut utiliser les autres layouts, qui eux seront bien indépendants de la résolution...

Certes, mais alors on fait quoi quand on a un vrai besoin ? Dans mon cas, on peut surligner du texte (dans une image), et j'ai besoin de pouvoir placer une icone à côté du passage surligné. Je connais les coordonnées à l'écran du surlignage, qui est fait en dur dans l'image, et je ne vois pas trop comment faire à part placer un bouton là où je le veux, au pixel près.

En fait, il existe une solution, et elle est toute simple : le RelativeLayout. J'en ai déjà parlé dans un précédent billet, le RelativeLayout est assez sympa car en fait on peut placer dedans des Views relativement à d'autres Views où aux limites du layout... En fait, par défaut un élément placé sur un RelativeLayout sera disposé relativement au coin supérieur gauche. Si on lui applique une marge, on peut donc réussir à le placer à n'importe quel endroit sur ce layout. Et voilà, en pratique le RelativeLayout peut se comportement exactement comme l'AbsoluteLayout.

Voici un bout de code non testé pour donner une idée de comment s'en servir :

int x = position X en pixels;
int y = position Y en pixels;

RelativeLayout l = new RelativeLayout(...);
RelativeLayout.LayoutParams params;

Button b = new Button(...);
params = new RelativeLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
params.leftMargin = x;
params.topMargin = y;
l.addView(b, params);

Je vous laisse compléter les trous, ce n'est pas bien méchant. J'ai appliqué ça au boulot, et j'ai enfin obtenu le résultat que je voulais (j'ai placé mon RelativeLayout dans le FrameLayout qui contenait déjà les images, histoire que tout soit en superposition...)
A noter qu'il ne sert à rien de faire 1 layout par View (ici Button), on peut mettre tous ceux qu'on veut sur le même RelativeLayout.

Solution tirée de StackOverflow...

12oct/100

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.