Xamarin.Android GridLayout

El GridLayout es una nueva subclase ViewGroup que admite la creación de vistas en una cuadrícula 2D, similar a una tabla HTML, como se muestra a continuación:

Cropped GridLayout displaying four cells

GridLayout funciona con una jerarquía de vistas planas, donde las vistas secundarias establecen sus ubicaciones en la cuadrícula especificando las filas y columnas en las que deben estar. De este modo, el GridLayout puede colocar vistas en la cuadrícula sin necesidad de que las vistas intermedias proporcionen una estructura de tabla, como se ve en las filas de tabla usadas en TableLayout. Al mantener una jerarquía plana, GridLayout puede diseñar con más rapidez sus vistas secundarias. Echemos un vistazo a un ejemplo para ilustrar lo que significa realmente este concepto en el código.

Crear un diseño de cuadrícula

El siguiente XML agrega varios TextViewcontroles a un GridLayout.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"    
        android:rowCount="2"
        android:columnCount="2">
     <TextView
            android:text="Cell 0"
            android:textSize="14dip" />
     <TextView
            android:text="Cell 1"
            android:textSize="14dip" />
     <TextView
            android:text="Cell 2"
            android:textSize="14dip" />
     <TextView
            android:text="Cell 3"
            android:textSize="14dip" />
</GridLayout>

El diseño ajustará los tamaños de fila y columna para que las celdas puedan ajustarse a su contenido, como se muestra en el diagrama siguiente:

Diagram of layout showing two cells on the left smaller than on the right

Esto da como resultado la siguiente interfaz de usuario cuando se ejecuta en una aplicación:

Screenshot of GridLayoutDemo app displaying four cells

Especificar orientación

Observe que en el XML anterior, cada TextView no especifica una fila o columna. Cuando no se especifican, el GridLayout asigna cada vista secundaria en orden, en función de la orientación. Por ejemplo, cambiemos la orientación de GridLayout del valor predeterminado, que es horizontal, a vertical de la siguiente manera:

<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"    
        android:rowCount="2"
        android:columnCount="2"
        android:orientation="vertical">
</GridLayout>

Ahora, colocará GridLayout las celdas de arriba a abajo en cada columna, en lugar de izquierda a derecha, como se muestra a continuación:

Diagram illustrating how cells are positioned in vertical orientation

Esto da como resultado la siguiente interfaz de usuario en tiempo de ejecución:

Screenshot of GridLayoutDemo with cells positioned in vertical orientation

Especificar posición explícita

Si queremos controlar explícitamente las posiciones de las vistas secundarias en GridLayout, podemos establecer sus layout_row atributos y layout_column. Por ejemplo, el siguiente XML dará como resultado el diseño que se muestra en la primera captura de pantalla (mostrada anteriormente), independientemente de la orientación.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"    
        android:rowCount="2"
        android:columnCount="2">
     <TextView
            android:text="Cell 0"
            android:textSize="14dip"
            android:layout_row="0"
            android:layout_column="0" />
     <TextView
            android:text="Cell 1"
            android:textSize="14dip"
            android:layout_row="0"
            android:layout_column="1" />
     <TextView
            android:text="Cell 2"
            android:textSize="14dip"
            android:layout_row="1"
            android:layout_column="0" />
     <TextView
            android:text="Cell 3"
            android:textSize="14dip"
            android:layout_row="1"
            android:layout_column="1"  />
</GridLayout>

Especificación del espaciado

Tenemos un par de opciones que proporcionarán espaciado entre las vistas secundarias de la GridLayout. Podemos usar el atributo layout_margin para establecer el margen en cada vista secundaria directamente, como se muestra a continuación

<TextView
            android:text="Cell 0"
            android:textSize="14dip"
            android:layout_row="0"
            android:layout_column="0"
            android:layout_margin="10dp" />

Además, en Android 4, ahora hay disponible una nueva vista de espaciado de uso general denominada Space. Para usarlo, simplemente agréguelo como una vista secundaria. Por ejemplo, el XML siguiente agrega una fila adicional al GridLayout estableciendo su rowcount en 3 y agrega una vista Space que proporciona espaciado entre el TextViews.

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"    
        android:rowCount="3"
        android:columnCount="2"
        android:orientation="vertical">
     <TextView
            android:text="Cell 0"
            android:textSize="14dip"
            android:layout_row="0"
            android:layout_column="0" />
     <TextView
            android:text="Cell 1"
            android:textSize="14dip"
            android:layout_row="0"        
            android:layout_column="1" />
     <Space
            android:layout_row="1"
            android:layout_column="0"
            android:layout_width="50dp"         
            android:layout_height="50dp" />    
     <TextView
            android:text="Cell 2"
            android:textSize="14dip"
            android:layout_row="2"        
            android:layout_column="0" />
     <TextView
            android:text="Cell 3"
            android:textSize="14dip"
            android:layout_row="2"        
            android:layout_column="1" />
</GridLayout>

Este XML crea espaciado en el GridLayout como se muestra a continuación:

Screenshot of GridLayoutDemo illustrating larger cells with spacing

La ventaja de usar la nueva vista Space es que permite el espaciado y no requiere que establezcamos atributos en cada vista secundaria.

Expansión de columnas y filas

El GridLayout también admite celdas que abarcan varias columnas y filas. Por ejemplo, supongamos que agregamos otra fila que contiene un botón a la GridLayout como se muestra a continuación:

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"    
        android:rowCount="4"
        android:columnCount="2"
        android:orientation="vertical">
     <TextView
            android:text="Cell 0"
            android:textSize="14dip"
            android:layout_row="0"
            android:layout_column="0" />
     <TextView
            android:text="Cell 1"
            android:textSize="14dip"
            android:layout_row="0"        
            android:layout_column="1" />
     <Space
            android:layout_row="1"
            android:layout_column="0"
            android:layout_width="50dp"        
            android:layout_height="50dp" />   
     <TextView
            android:text="Cell 2"
            android:textSize="14dip"
            android:layout_row="2"        
            android:layout_column="0" />
     <TextView
            android:text="Cell 3"
            android:textSize="14dip"        
            android:layout_row="2"        
            android:layout_column="1" />
     <Button
            android:id="@+id/myButton"
            android:text="@string/hello"        
            android:layout_row="3"
            android:layout_column="0" />
</GridLayout>

Esto dará lugar a que la primera columna del GridLayout se extienda para dar cabida al tamaño del botón, como se muestra aquí:

Screenshot of GridLayoutDemo with button spanning only the first column

Para evitar que la primera columna se extienda, podemos establecer el botón para abarcar dos columnas estableciendo su panel de columnas de la siguiente manera:

<Button
    android:id="@+id/myButton"
    android:text="@string/hello"       
    android:layout_row="3"
    android:layout_column="0"
    android:layout_columnSpan="2" />

Esto da como resultado un diseño para el TextViewsque es similar al diseño que teníamos anteriormente, con el botón agregado a la parte inferior del GridLayout como se muestra a continuación:

Screenshot of GridLayoutDemo with button spanning both columns