Pages

dimanche 26 mai 2013

GridLayout pour créer des tableaux ou des vues complexes

Pour créer un tableau l’API Android met à disposition depuis sa version 1, le TableLayout. Je vous laisse lire mon article sur le sujet. Mais ce composant ne permet pas de gérer tous les cas. Par exemple vous ne pouvez pas faire de la fusion de lignes (seulement de colonnes) et vous ne pouvez pas placer un élément directement à la ligne et colonne que vous voulez.


Depuis la sortie d’Ice-cream Sandwich (nom de code de la version 4.0 API level 14), Android a mis à disposition le composant android.widget.GridLayout. Ce composant permet de composer des vues plus évoluées plus facilement....

des formulaires... des tableaux

Créer ce genre d’écran via les layouts standards demande parfois beaucoup d’ingéniosité, et vous oblige à définir une hiérarchie complexe de layouts auto imbriqués. Cet empilement de layouts dégrade les performances et empêche une bonne utilisation des outils de développement. 

Le GridLayout permet de résoudre ces problèmes. Quand vous utilisez ce layout, vous devez imaginer la disposition finale et découper l’espace en lignes et en colonnes. 



L’utilisation est assez simple et est très similaire à l’utilisation d’un LinearLayout qu’on remplit ligne à ligne. Prenons un premier exemple avec la définition de la vue via une vue xml


<GridLayout
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:layout_alignLeft="@+id/textView"
           android:useDefaultMargins="false"
           android:alignmentMode="alignBounds"
           android:columnCount="4">

       <ImageView
               android:id="@+id/imageView"
               android:src="@drawable/logo3"
               android:layout_columnSpan="4"
               android:layout_gravity="center_horizontal"
               android:paddingBottom="15dp"/>

       <TextView
               android:text="You can send a comment on this article :"
               android:textSize="16dip"
               android:layout_columnSpan="4"
               android:layout_gravity="left"
               />

       <TextView
               android:text="Email address:"
               android:layout_gravity="right"
               />

       <EditText android:ems="@integer/size_edittext"/>

       <TextView
               android:text="Comment:"
               android:layout_column="0"
               android:layout_gravity="right"
               />

       <EditText
             android:ems="@integer/size_edittext"
             android:maxLines="4"
             android:minLines="2"
             />

       <Space
               android:layout_row="4"
               android:layout_column="0"
               android:layout_columnSpan="3"
               android:layout_gravity="fill"
               />

       <Button
               android:text="Go"
               android:layout_row="5"
               android:layout_column="3"
               />
   </GridLayout>

Ce code vous donnera le résultat suivant qui vous permettra d’avoir le même comportement que vous soyez en mode paysage ou portrait.


Dans un premier temps vous pouvez observer que les éléments ajoutés au GridLayout ne possèdent pas les propriétés width et height. En effet même si le GUI Builder peut vous afficher une erreur, ces éléments ne sont pas obligatoires avec ce Layout et ils possèdent par défaut la valeur WRAP_CONTENT.

Placement des composants dans la grille
Si vous ne précisez rien, chaque composant sera ajouté selon son ordre de définition dans la grille. Si la grille fait 4 colonnes, le cinquième élément sera automatiquement placé à la ligne.

Vous pouvez choisir de fusionner des colonnes ou des lignes en ajoutant les propriétés suivantes
android:layout_rowSpan="2"
android:layout_columnSpan="4"

Pour définir la position du composant dans la cellule vous devrez utiliser
android:layout_gravity="fill"

Vous pouvez explicitement choisir la cellule ou le composant est placé comme pour le bouton dans notre exemple ci dessus
android:layout_row="5"
android:layout_column="3"

Les espaces
Quand vous utilisez le GridLayout il est important de penser aux zones d’extension quand la résolution ou la taille de l’écran va changer. Sur notre exemple vous pouvez observer que le bouton se retrouve toujours dans le coin inférieur droit.

Quand vous avez toute une zone de vide vous pouvez utiliser le composant Space apparu également à partir de la version 14 de l’API.

Les propriétés
Vous pouvez ajouter différentes propriétés au GridLayout pour définir son rendu à l’écran. La plus importante est le nombre de colonnes (android:columnCount) mais vous pouvez aussi définir le maximum de lignes, l’alignement....

Peupler un GridLayout via l’API Java
Comme la plupart des éléments vous pouvez les créer et les gérer via l’API Java. Nous allons prendre un autre exemple qui nous permettra de montrer l’intérêt de ce nouveau Layout pour créer des tableaux par rapport à un TableLayout.

Nous allons partir de la définition d’une vue assez simple

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

   <GridLayout
           android:layout_width="fill_parent"
           android:layout_height="fill_parent"
           android:layout_alignLeft="@+id/gridView"
           android:useDefaultMargins="false"
           android:alignmentMode="alignBounds"
           android:columnCount="4">
   </GridLayout>
</RelativeLayout>


Nous allons maintenant créer un mini calendrier au niveau de notre activité. Je ne vais pas donner le code complet car l’intérêt est limité mais seulement les grandes lignes (vous pouvez le récupérer sur Github)

public class MainActivity extends Activity {
   //Handle sur le GridLayout défini dans le fichier layout
   private GridLayout myGridLayout;
   //...

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_grid);

       myGridLayout = (GridLayout) findViewById(R.id.gridView);
       dessinerVue();
   }

   @Override
   protected void onResume() {
       super.onResume();
       dessinerVue();
   }

   protected void dessinerVue() {
       myGridLayout.removeAllViews();
   
       TextView textView = new TextView(this);
       textView.setGravity(Gravity.CENTER);
       textView.setText("Mon texte");
       textView.setLayoutParams(
              new GridLayout.LayoutParams(
                       GridLayout.spec(row, GridLayout.FILL),
                       GridLayout.spec(column, GridLayout.FILL));
       myGridLayout.addView(createTextView("H", 0, 0, R.color.grey_dark, false, false));

       //....
   }
}

Sur ce principe vous arriverez un écran similaire au tableau présenter au début de l'article

Conclusion
Ce layout reprend la plupart des caractéristiques des layouts existants sous Android et permet d’éviter d’empiler les layouts pour arriver à une disposition complexe des composants sur votre écran. Je n’ai pas abordé le problème de la rétrocompatibilité mais Android met à disposition les librairies vous permettant d’utiliser ces fonctionnalités sur les anciennes versions de l’API. Vous trouverez ces librairies dans votre répertoire d’installation du SDK [android-sdk]\extras\android\support\.

Références
http://developer.android.com/reference/android/widget/GridLayout.html
http://android-developers.blogspot.fr/2011/11/new-layout-widgets-space-and-gridlayout.html

Les sources du code exposé dans cet article sont disponibles sous Github
https://github.com/javamind/annexe/tree/master/GridLayoutExample/GridLayoutExample



Aucun commentaire:

Enregistrer un commentaire

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.