Download - Contenedores Layout

Transcript
Page 1: Contenedores Layout

CONTENEDORES LAYOUT

Interfaz de usuario en Android: LayoutsEn el artículo anterior del curso, donde desarrollamos una sencilla aplicación Android desde cero, ya hicimos algunos comentarios sobre los layouts. Como ya indicamos, los layouts son elementos no visuales destinados a controlar la distribución, posición y dimensiones de los controles que se insertan en su interior. Estos componentes extienden a la clase base ViewGroup, como muchos otros componentes contenedores, es decir, capaces de contener a otros controles. En el post anterior conocimos la existencia de un tipo concreto de layout, LinearLayout, aunque Android nos proporciona algunos otros. Veámos cuántos y cuáles.

FrameLayout

Éste es el más simple de todos los layouts de Android. Un FrameLayout coloca todos sus controles hijos alineados con su esquina superior izquierda, de forma que cada control quedará oculto por el control siguiente (a menos que éste último tenga transparencia). Por ello, suele utilizarse para mostrar un único control en su interior, a modo de contenedor (placeholder) sencillo para un sólo elemento sustituible, por ejemplo una imagen.

Los componentes incluidos en un FrameLayout podrán establecer sus propiedades android:layout_width y android:layout_height, que podrán tomar los valores “match_parent” (para que el control hijo tome la dimensión de su layout contenedor) o “wrap_content” (para que el control hijo tome la dimensión de su contenido). NOTA: Si estás utilizando una versión de la API de Android inferior a la 8 (Android 2.2), en vez de “match_parent” deberás utilizar su equivalente “fill_parent”.

Ejemplo:

1234567891011

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

     <EditText android:id="@+id/TxtNombre"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:inputType="text" /> </FrameLayout>

Page 2: Contenedores Layout

Con el código anterior conseguimos un layout tan sencillo como el siguiente:

LinearLayout

El siguiente tipo de layout en cuanto a nivel de complejidad es el LinearLayout. Este layout apila uno tras otro todos sus elementos hijos de forma horizontal o vertical según se establezca su propiedad android:orientation.

Al igual que en un FrameLayout, los elementos contenidos en un LinearLayout pueden establecer sus propiedades android:layout_width y android:layout_height para determinar sus dimensiones dentro del layout. Pero en el caso de un LinearLayout, tendremos otro parámetro con el que jugar, la propiedad android:layout_weight.

12345678910111213141

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">

     <EditText android:id="@+id/TxtNombre"        android:layout_width="match_parent"        android:layout_height="match_parent" />     <Button android:id="@+id/BtnAceptar"        android:layout_width="wrap_content"        android:layout_height="match_parent" /> </LinearLayout>

Page 3: Contenedores Layout

5

Esta propiedad nos va a permitir dar a los elementos contenidos en el layout unas dimensiones proporcionales entre ellas. Esto es más dificil de explicar que de comprender con un ejemplo. Si incluimos en un LinearLayout vertical dos cuadros de texto (EditText) y a uno de ellos le establecemos un layout_weight=”1″ y al otro un layout_weight=”2″ conseguiremos como efecto que toda la superficie del layout quede ocupada por los dos cuadros de texto y que además el segundo sea el doble (relación entre sus propiedades weight) de alto que el primero.

12345678910111213141516171819

<LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">

     <EditText android:id="@+id/TxtDato1"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:inputType="text"        android:layout_weight="1" />     <EditText android:id="@+id/TxtDato2"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:inputType="text"        android:layout_weight="2" /> </LinearLayout>

Con el código anterior conseguiríamos un layout como el siguiente:

Page 4: Contenedores Layout

Así pues, a pesar de la simplicidad aparente de este layout resulta ser lo suficiente versátil como para sernos de utilidad en muchas ocasiones.

TableLayout

Un TableLayout permite distribuir sus elementos hijos de forma tabular, definiendo las filas y columnas necesarias, y la posición de cada componente dentro de la tabla.

La estructura de la tabla se define de forma similar a como se hace en HTML, es decir, indicando las filas que compondrán la tabla (objetos TableRow), y dentro de cada fila las columnas necesarias, con la salvedad de que no existe ningún objeto especial para definir una columna (algo así como un TableColumn) sino que directamente insertaremos los controles necesarios dentro del TableRow y cada componente insertado (que puede ser un control sencillo o incluso otro ViewGroup) corresponderá a una columna de la tabla. De esta forma, el número final de filas de la tabla se corresponderá con el número de elementos TableRowinsertados, y el número total de columnas quedará determinado por el número de componentes de la fila que más componentes contenga.

Por norma general, el ancho de cada columna se corresponderá con el ancho del mayor componente de dicha columna, pero existen una serie de propiedades que nos ayudarán a modificar este comportamiento:

android:stretchColumns. Indicará las columnas que pueden expandir para absorver el espacio libre dejado por las demás columnas a la derecha de la pantalla.

android:shrinkColumns. Indicará las columnas que se pueden contraer para dejar espacio al resto de columnas que se puedan salir por la derecha de la palntalla.

android:collapseColumns. Indicará las columnas de la tabla que se quieren ocultar completamente.

Todas estas propiedades del TableLayout pueden recibir una lista de índices de columnas separados por comas (ejemplo: android:stretchColumns=”1,2,3″) o un asterisco para indicar que debe aplicar a todas las columnas (ejemplo: android:stretchColumns=”*”).

Page 5: Contenedores Layout

Otra característica importante es la posibilidad de que una celda determinada pueda ocupar el espacio de varias columnas de la tabla (análogo al atributo colspan de HTML). Esto se indicará mediante la propiedad android:layout_span del componente concreto que deberá tomar dicho espacio.

Veamos un ejemplo con varios de estos elementos:

1234567891011121314151617181920212223

<TableLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent" >     <TableRow>        <TextView android:text="Celda 1.1" />        <TextView android:text="Celda 1.2" />        <TextView android:text="Celda 1.3" />    </TableRow>

     <TableRow>        <TextView android:text="Celda 2.1" />        <TextView android:text="Celda 2.2" />        <TextView android:text="Celda 2.3" />    </TableRow>

     <TableRow>        <TextView android:text="Celda 3.1"               android:layout_span="2" />        <TextView android:text="Celda 3.2" />    </TableRow></TableLayout>

El layout resultante del código anterior sería el siguiente:

Page 6: Contenedores Layout

GridLayout

Este tipo de layout fue incluido a partir de la API 14 (Android 4.0) y sus características son similares al TableLayout, ya que se utiliza igualmente para distribuir los diferentes elementos de la interfaz de forma tabular, distribuidos en filas y columnas. La diferencia entre ellos estriba en la forma que tiene el GridLayout de colocar y distribuir sus elementos hijos en el espacio disponible. En este caso, a diferencia del TableLayout indicaremos el número de filas y columnas como propiedades del layout, mediante android:rowCount y android:columnCount. Con estos datos ya no es necesario ningún tipo de elemento para indicar las filas, como hacíamos con el elemento TableRow del TableLayout, sino que los diferentes elementos hijos se irán colocando ordenadamente por filas o columnas (dependiendo de la propiedad android:orientation) hasta completar el número de filas o columnas indicadas en los atributos anteriores. Adicionalmente, igual que en el caso anterior, también tendremos disponibles las propiedades android:layout_rowSpan y android:layout_columnSpan para conseguir que una celda ocupe el lugar de varias filas o columnas.

Existe también una forma de indicar de forma explícita la fila y columna que debe ocupar un determinado elemento hijo contenido en el GridLayout, y se consigue utilizando los atributos android:layout_row y android:layout_column. De cualquier forma, salvo para configuraciones complejas del grid no suele ser necesario utilizar estas propiedades.

Con todo esto en cuenta, para conseguir una distribución equivalente a la del ejemplo anterior del TableLayout, necesitaríamos escribir un código como el siguiente:

123456

<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="3"    android:orientation="horizontal" > 

Page 7: Contenedores Layout

78910111213141516171819202122

        <TextView android:text="Celda 1.1" />        <TextView android:text="Celda 1.2" />        <TextView android:text="Celda 1.3" />         <TextView android:text="Celda 2.1" />        <TextView android:text="Celda 2.2" />        <TextView android:text="Celda 2.3" />         <TextView android:text="Celda 3.1"               android:layout_columnSpan="2" />         <TextView android:text="Celda 3.2" /> </GridLayout>

RelativeLayout

El último tipo de layout que vamos a ver es el RelativeLayout. Este layout permite especificar la posición de cada elemento de forma relativa a su elemento padre o a cualquier otro elemento incluido en el propio layout. De esta forma, al incluir un nuevo elemento X podremos indicar por ejemplo que debe colocarse debajo del elemento Y y alineado a la derecha del layout padre. Veamos esto en el ejemplo siguiente:

123456789

<RelativeLayout        xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="match_parent"        android:layout_height="match_parent" >         <EditText android:id="@+id/TxtNombre"              android:layout_width="match_parent"              android:layout_height="wrap_content"              android:inputType="text" /> 

Page 8: Contenedores Layout

10111213141516

        <Button android:id="@+id/BtnAceptar"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_below="@id/TxtNombre"            android:layout_alignParentRight="true" /></RelativeLayout>

En el ejemplo, el botón BtnAceptar se colocará debajo del cuadro de texto TxtNombre (android:layout_below=”@id/TxtNombre”) y alineado a la derecha del layout padre (android:layout_alignParentRight=”true”), Quedaría algo así:

Al igual que estas tres propiedades, en un RelativeLayout tendremos un sinfín de propiedades para colocar cada control justo donde queramos. Veamos las principales [creo que sus propios nombres explican perfectamente la función de cada una]:

Posición relativa a otro control:

android:layout_above. android:layout_below. android:layout_toLeftOf. android:layout_toRightOf. android:layout_alignLeft. android:layout_alignRight. android:layout_alignTop. android:layout_alignBottom.

Page 9: Contenedores Layout

android:layout_alignBaseline.

Posición relativa al layout padre:

android:layout_alignParentLeft. android:layout_alignParentRight. android:layout_alignParentTop. android:layout_alignParentBottom. android:layout_centerHorizontal. android:layout_centerVertical. android:layout_centerInParent.

Opciones de margen (también disponibles para el resto de layouts):

android:layout_margin. android:layout_marginBottom. android:layout_marginTop. android:layout_marginLeft. android:layout_marginRight.

Opciones de espaciado o padding (también disponibles para el resto de layouts):

android:padding. android:paddingBottom. android:paddingTop. android:paddingLeft. android:paddingRight.

Linear Layout

LinearLayout es un contenedor que utiliza el modelo de caja para desplegar los elementos que están dentro de él. Los widgets y contenedores secundarios que se declaren dentro de un elemento <LinearLayout> se alinearán en una columna o en un fila, uno detrás de otro.

Para los que han trabajado con FLEX y XUL no me dejarán mentir en el hecho de que este modelo utiliza el concepto de “caja” como la principal unidad de diseño. Por ello, si te decides a utilizar LinearLayout en el diseño de tus interfaces de usuario, deberás tomar en cuenta aspectos como la anidación entre elementos, qué propiedades tendrá cada caja y cómo será la alineación entre cada una de ellas.

Conceptos y propiedades

Page 10: Contenedores Layout

Para la buena configuración de un contenedor LinearLayout debes conocer 5 áreas principales que te ayudarán a definir el aspecto visual del mismo: la orientación (orientation), el llenado del modelo (fill model), el peso (weight), la gravedad (gravity) y el relleno (padding).

Orientación

La orientación (orientation) nos ayudará a indicar si el LinearLayout representa una columna o una fila. Para definirla, hay que agregar la propiedad android:orientation en el elemento <LinearLayout> del XML, y los valores que podemos escribir son horizontal o vertical; si es horizontal entonces trabajaremos el layout a modo de fila y si es vertical lo trabajaremos a modo de columna.

También hay que saber que la orientación puede ser modificada en tiempo de ejecución utilizando el método setOrientation() de la clase LinearLayout, pasando como parámetro HORIZONTAL o VERTICAL según sea el caso.

Llenado del modelo

Para comprender este concepto vamos a guiarnos por un ejemplo. Supongamos que tenemos una serie de radio buttons. Cada uno de estos elementos tienen un tamaño natural basado en el largo de su texto. La combinación de cada uno de los tamaños de los radio buttons probablemente no coincidan exactamente con el ancho de la pantalla del dispositivo (tomando en cuenta que si hablamos de Android tenemos una amplia variedad de tamaños). De la misma forma, está el tema de qué hacer con el espacio restante de la pantalla que no está siendo utilizado.

Por esta razón, a todos los elementos contenidos en un LinearLayout debemos definirles un valor para los atributos android:layout_width y android:layout_height. Tenemos tres posibles opciones:

Podemos asignar una dimensión específica, por ejemplo: 150px que se deberá mostrar de esta forma sin importar la resolución de la pantalla que se tenga.

Podemos definir el valor wrap_content, por medio del cual le indicamos a la aplicación que el elemento sólo deberá ocupar lo correspondiente a su tamaño natural, a menos que sea demasiado grande, en este caso Android usará la propiedad word-wrap según sea necesario para que el elemento se ajuste.

Por último, podemos utilizar el valor fill_parent, que indica que el elemento es libre de utilizar todo el espacio disponible del contenedor en el que se encuentra.

Comúnmente, utilizarás las dos últimas opciones ya que son independientes del tamaño de pantalla del dispositivo y así será más fácil para Android acomodar los widgets que utilizas en tus aplicaciones.

Peso

Page 11: Contenedores Layout

Definamos otro escenario. Supongamos que tenemos dos campos de varias líneas en una columna y queremos que ocupen el espacio sobrante después de acomodar otros controles que ya han ocupado su respectivo espacio. Para hacer esto, además de definir las propiedades android:layout_height (para columnas) y android:layout_width (para filas), habrá que definir un valor para el atributo android:layout_weight. Esta propiedad indica la proporción del espacio libre que le corresponde a ese widget.

Si por ejemplo definimos el valor “1″ en el atributo android:layout_weight de dos widgets distintos, el espacio libre se repartirá de manera completamente equitativa entre ellos. Por otro lado si tenemos definido un widget con el valor de “1″ en este atributo y “2″ para otro widget, esto hará que el segundo widget ocupe el doble del espacio libre con respecto al primero y así sucesivamente.

Gravedad

Por default, los elementos se alinean a partir de la esquina superior izquierda. Por lo tanto, si creamos una fila de widgets de forma horizontal dentro de un contenedor de tipo LinearLayout, todos ellos se empezarán a alinear a partir de este punto y seguirá ese flujo hasta que todos los widgets aparezcan en la interfaz.

Para cambiar este flujo natural utilizamos el atributo android:layout_gravity o desde el código Java con el método setGravity(), para indicarle al elemento y a su contenedor cómo deberá alinearse en la pantalla.

Para una columna de widgets, los valores que le podemos asignar a este atributo son: left, center_horizontal y right. En cambio, para una fila de elementos, se toman en cuenta los textos que los acompañan de modo que queden alineados en la línea de base (que es la línea invisible que indica el pie de la fila), aunque es posible indicar un valor de gravedad de center_vertical para que de este modo los elementos queden centrados de manera vertical y no queden al ras de la línea inferior del renglón.

Relleno

Por default, los widgets se apilan de manera seguida una junto a otro, cosa que algunas veces no resulta muy agradable visualmente. Por ello, para aumentar el espacio en blanco entre cada uno de ellos utilizamos el atributo android:padding o directamente en el código Java en tiempo de ejecución con el método setPadding().

El relleno es un valor que indica el espacio existente entre los límites que ocupa el widget en sí y la línea que marca el inicio del contenedor. El relleno equivale al margen que se define en un documento de procesador de textos.

La propiedad android:padding nos permite definir un sólo valor de relleno para los cuatro lados del widget. Si queremos que el relleno aplique únicamente a alguno de los lados del elemento o bien, definir valores distintos para cada lado, podemos utilizar las propiedades

Page 12: Contenedores Layout

android:paddingLeft, android:paddingRight, android:paddingTop, y android:paddingBottom.

Para definir el valor de este atributo tenemos una serie de unidades de medidas que podemos utilizar:

dp – píxeles independientes de la densidad: es una unidad abstracta que se basa en la densidad de píxeles de la pantalla. Sirve para garantizar que las cosas tengan las mismas medidas físicas en cualquier pantalla. Como regla, hay que tener en cuenta que 160dp equivaldrá a una pulgada (o, lo que es lo mismo, 63dp serán un centímetro) en cualquier pantalla.

sp – píxeles independientes de la escala: es igual que la unidad dp, pero escalada según el tamaño de fuente escogido por el usuario. Es la unidad recomendada para definir el tamaño de los textos que se muestran en pantalla.

pt – puntos: representan 1/72 partes de una pulgada (o, más o menos, 1/28 de un centímetro) en cualquier pantalla.

px – píxeles: no se recomienda utilizar esta unidad, porque las pantallas tienen diferentes densidades y tamaños, por lo que los elementos dimensionados en píxeles se pueden ver de formas muy diferentes.

mm – milímetros: medida directa del elemento en pantalla, en unidades más internacionales.

in – pulgadas: medida directa del elemento en pantalla, en unidades anglosajonas.

EJEMPLO

1. Creamos un nuevo proyecto Android llamado AndroideityLinearLayout con la versión Android 2.1 update 1.

2. En el archivo main.xml del directorio res > layout vamos a definir lo siguiente:

Page 13: Contenedores Layout

El contenedor principal de nuestro layout es un elemento <LinearLayout> que tiene una orientación vertical. Dentro de él, tenemos dos elementos RadioGroup, el primero con orientación horizontal y el segundo vertical. Esta primera definición nos hará ver cómo es que cambia la disposición de los elementos a la hora de mostrarse en pantalla.

Hemos definido 5 radio buttons en total con los textos correspondientes a los cambios que ejecutarán sobre el layout cada vez que seleccionemos alguno de ellos. Los textos los hemos separado creando recursos de tipo String dentro del archivo res > values > strings.xml y su contenido es el que te muestro a continuación:

Page 14: Contenedores Layout

3. Para poder ver cómo afectan los valores de los atributos en el diseño del layout, pasemos a escribir la parte de código Java que ejecutará nuestra aplicación. A continuación te pongo el código que deberá contener tu actividad principal, es decir, el archivo .java localizado en el directorio src.

Page 15: Contenedores Layout

4. Ya tenemos todo listo, ahora pasemos a ejecutar el proyecto para ver qué pasa.

Page 16: Contenedores Layout

La imagen anterior muestra el layout básico definido en el XML. Cada vez que nosotros seleccionemos alguno de los radio buttons, podremos ver en tiempo de ejecución los cambios en el diseño del layout que se van haciendo según lo que hemos definido a través del código del paso anterior.

Page 18: Contenedores Layout

Layout en Android II: Relative LayoutEscrito por Condesa | Saturday, July 16, 2011 a las 1:43 pm | 4 Comentarios

El segundo contenedor del que disponemos para crear interfaces en Android es el Relative Layout. Su principal característica es que los widgets que estén dentro de este contenedor basarán su posición en  relación con los otros elementos. De esta forma, podemos definir que el widget X quede debajo del widget Y y que éste a su vez se alinie verticalmente con el widget Z.

 

Conceptos y propiedades

Cabe mencionar que además de posicionar un elemento con respecto a otro del mismo nivel también podemos hacerlo con respecto al área que corresponde al RelativeLayout.

Este tipo de contenedor es una herramienta muy poderosa para cumplir con la tarea de diseñar interfaces de usuario ya que permite eliminar ViewGroups anidados, lo cuál es útil para reemplazar un diseño en el que tenemos una gran cantidad de grupos dentro de un contenedor de tipo LinearLayout y hacerlo más eficiente utilizando un RelativeLayout.

Entre los atributos que nos sirven para posicionar los elementos con respecto a otros están:

android:layout_above indica que el elemento se posicionará justo arriba del elemento que tiene el ID definido como valor de este atributo.

android:layout_toLeftOf indica que el elemento se posionará a la izquierda del elemento cuyo ID coincida con el definido en el valor de este atributo.

Page 19: Contenedores Layout

android:layout_toRightOf posiciona al elemento a la derecha del elemento cuyo ID coincida con el proporcionado en el valor de este atributo.

android:layout_bottom posiciona al elemento debajo del que tenga la ID proporcionada en el valor del atributo.

En el listado anterior tendremos que proporcionar siempre un ID de otro elemento, ejemplo: android:layout_toLeftOf=”@id/ok” dónde el elemento cuyo id es Ok ya se definió anteriormente en el archivo XML.

De la misma forma existen atributos cuyo valor se maneja con true y false y que nos sirven a posicionar a los elementos con respecto al contenedor en el que se encuentran, entre ellos tenemos:

android:layout_alignParentTop que le indica al widget que su borde superior deberá estar alineado con el borde superior del contenedor.

android:layout_alignParentBottom que le indica al widget que su borde inferior deberá estar alineado con el borde inferior del contenedor.

android:layout_alignParentLeft que le indica al widget que su borde izquierdo deberá estar alineado con el borde izquierdo del contenedor.

android:layout_alignParentRight que le indica al widget que su borde derecho deberá estar alineado con el borde derecho del contenedor.

android:layout_centerHorizontal permite centrar horizontalmente al widget con respecto a su contenedor.

android:layout_centerVertical permite centrar verticalmente al widget con respecto a su contenedor.

Cosas a considerar

Para que podamos trabajar con los atributos listados arriba, es necesario que cuides dos puntos muy importantes:

1. Definir identificadores (id’s) por medio del atributo android:id en cada uno de los elementos que estarán dentro del contenedor principal RelativeLayout. En esta parte el valor de los atributos irá con el formato android:id=”@+id/[miId]“.

2. Poner la referencia correcta hacia otros elementos del layout con la ayuda del formato “@id/elIdDelOtroElemento”, NOTA QUE AQUÍ OMITIMOS EL SIGNO DE +. Por ejemplo: android:layout_alignTop=”@id/ok”.

 

Orden en que se acomodan los elementos

Algunas veces puede resultar complicado alinear todos los elementos según el diseño que queramos obtener y esto se debe a orden de evaluación que toma Android para llevar a cabo esta tarea. Android hace una sola revisión a través del archivo XML y calcula el tamaño y

Page 20: Contenedores Layout

posición de cada uno de los elementos que va encontrando en la definición del layout. Por lo que a la hora de trabajar con este tipo de contenedor tienes que saber que:

1. No puedes hacer referencia a un elemento que aún no ha sido definido. Es decir, si por ejemplo ocupamos un EditText para comodar un botón, el EditText deberá estar definido antes de hacer el llamado en el atributo del Button porque sino Android lo tomará como un error.

2. Hay que tener cuidado a la hora de utilizar el valor fill_parent para los atributos android:layout_width y android:layout_height para evitar que un elemento termine acaparándose el espacio que le corresponda a algún elemento posterior que dependa de éste para mostrarse.

 

Pasemos al código…

Para aterrizar los conceptos vistos y tener claro cómo se comporta un contenedor de tipo RelativeLayout vamos a poner en marcha un proyecto llamado AndroideityRelativeLayout con la versión Android 2.1 update 1.

1. Modificamos el layout definido en el archivo main.xml del directorio res > layout para que nos quede de la siguiente forma:

Page 21: Contenedores Layout

Como puedes ver, haremos un sencillo formulario utilizando un TextView para desplegar un mensaje, un EditText que abarcará todo el ancho del contenedor y abajo dos botones alineados a la derecha del contenedor.

El TextView se posiciona tomando el flujo natural que va desde el punto superior izquierdo. El EditText ya se posiona tomando en cuenta el TextView, de manera que indicamos que deberá aparecer debajo de él. Para el botón Aceptar, indicamos que aparecerá debajo del EditText y que su alineación será a la derecha con respecto al contenedor.

Por último, el botón Cancelar está definido para que aparezca a la izquierda del botón Aceptar y que además su borde superior se encuentre alienado con el borde superior del botón Aceptar.

2. Ejecutamos el proyecto y vemos el resultado visual descrito hace un momento:

Page 22: Contenedores Layout

Algunas veces para mejorar el aspecto visual de nuestro layout cuando utilizamos este tipo de contenedor está en jugar con el valor de android:padding de los elementos para que el resultado final sea más agradable.

Cuando empiezas a trabajar con este tipo de layout puede resultarte un poco tedioso el estar definiendo la posición de cada elemento, pero su utilización depende únicamente de la necesidad de diseño que tengas en determinado momento. A veces es muy efectivo utilizarlo y otras veces puedes optar por utilizar otras opciones.

eguramente alguna vez te tocó trabajar con las famosas (y ya no tan cool) tablas en HTML, si es así, tal vez debas conocer el tercer contenedor de Android llamado TableLayout, que te ayudará a posicionar tus widgets con la ayuda de celdas. Nosotros controlamos el número de columnas y filas, las primeras pueden adaptarse al contenido que le queramos asignar mostrándose más estrechas o más amplias según sea el caso.

Los elementos TableLayout trabajan en conjunto con los elementos TableRow. De esta forma podemos controlar el número de filas que aparecerán en nuestra tabla.

Por otro lado, Android es el que controla el número de columnas que aparecerá en el layout según los widgets que necesitemos que aparezcan, tomando en cuenta de que de manera predeterminada habrá al menos una columna por cada widget contenida en una fila. Por ejemplo, si tenemos tres filas, una con dos widgets, una con tres widgets y otra con 4 widgets, habrá por lo menos 4 columnas para todo el layout.

Page 23: Contenedores Layout

Y así como HTML, es posible que un widget pueda tomar más de una columna con la ayuda del atributo android:layout_span cuyo valor será el número de columnas que queramos que el widget ocupe.

En el siguiente trozo de código creamos una tabla con una fila que contiene un TextView y un EditText que ocupará 3 columnas, por lo que al final, nuestra tabla tendrá hasta este punto 4 columnas.

Regularmente, los widgets comienzan a posicionarse empezando por la primera columna de la izquierda y se cuentan a partir del número cero. De esta forma, el TextView estará en la columna 0 y el EditText ocupará de la columna 1 a la 3. Esta característica de las tablas nos permitirá posicionar un widget en alguna columna en específico en caso de que la aplicación lo requiera a través del atributo android:layout_column cuyo valor será el de la columna en el que lo queramos posicionar sin olvidar que la primera columna lleva el número cero.

 

Widgets independientes de las filas

Como explicamos arriba, los elementos TableLayout contienen TableRow como elementos hijos inmediatos que son usados para desplegar los widgets de la aplicación. Sin embargo, es posible poner un widget en medio de las filas de la tabla. Para estos casos, el contenedor TableLayout se comporta de manera parecida a un LinearLayout con orientación vertical y los widgets que incluyamos tendrán el valor fill_parent para su atributo android:layout_width; de esta forma nos aseguramos de que estos widgets que andan sueltos medirán exactamente lo mismo que la fila más larga que tenga nuestro layout.

Tip: Para que obtengas un resultado visual más bonito si decides llevar a la práctica lo anterior, te recomiendo utilices un elemento de tipo View que te sirva como divisor. Por ejemplo, podrías declararlo como <View android:layout_height=”2px” android:background=”#FFFFFF” />. Claro está que puedes jugar con el color de la línea divisora.

 

Jugando con el ancho de las columnas

Page 24: Contenedores Layout

De manera predeterminada, las columnas en este tipo de layout toman como ancho el del widget que se encuentra dentro de cada una de ellas. Sin embargo, hay veces en las que el resultado visual no siempre será el deseado y es aquí cuando podemos hacer uso de la propiedad android:stretchColumns que aplica para el elemento TableLayout.

El valor aplicado a este atributo debe ser un número que corresponda a una columna (cuidando la regla de que la primera columna ocupa la posición cero), y en caso de que queramos aplicarlo a más de una columna, deberemos indicar el número de las columnas separadas por coma. El resultado final, será que la (s) columna (s) definida (s) podrán expandirse tanto como lo permita el espacio disponible que se tenga en la fila. Desde el código Java podemos también asignar esta propiedad haciendo uso del método setColumnStretchable().

Si queremos hacer lo contrario, tenemos a nuestra disposición el atributo android:shrinkColumns que de igual forma se aplica al elemento TableLayout. El valor para este atributo se define exactamente igual que en la explicación del párrafo anterior. Las columnas que aparezcan en esta propiedad utilizarán el ajuste de línea sobre su contenido para lograr disminuir el ancho de la misma. Esto resulta útil cuando queramos evitar que una columna que contiene mucho texto no se expanda a tal punto que empuje widgets como botones hasta el extremo derecho de la pantalla y podamos así tener un balance visual en el layout. Si queremos manipular esta propiedad en tiempo de ejecución podemos hacerlo utilizando el método setColumnShrinkable().

Por último, es importante mencionar el uso de otro atributo que es android:collapseColumns cuyo valor se determina como en los dos atributos arriba explicados. Lo que hace es que las columnas definidas en él formarán parte de la información de la tabla pero de forma invisible. Podemos manipular esta acción desde el código Java utilizando el método setColumnCollapsed() sobre el objeto de tipo TableLayout. El uso más común de esta propiedad es la de permitirle al usuario controlar las columnas que son de importancia para él y así mostrar aquellas con más prioridad sobre las que no lo son para así poder ocultarlas.

 

Pasemos al código…

Vamos a repasar lo que hemos explicado hasta el momento creando un proyecto llamado AndroideityTableLayout con la versión Android 2.1 update 1.

1. Creamos el layout editando el archivo main.xml del directorio res > layout. Notarás que vamos a utilizar un widget a modo de divisor como explicamos en una sección anterior de este post. Y vamos a trabajar con dos filas; la primera que albergará un TextView y un EditText y la segunda fila con dos botones.

Page 25: Contenedores Layout

2. Ejecutamos el código y veremos el siguiente resultado:

La línea divisora la hemos puesto de un color diferente para que notes cómo es que la definición de nuestro layout se refleja visualmente en el resultado final de la aplicación. Es un ejemplo muy sencillo pero que nos ayuda a comprender cómo es que se acomodan los elementos en un layout que utiliza columnas y filas para albergar los componentes visuales de Android.

Para tus aplicaciones puedes probar muchos atributos más que puedes consultar en la documentación oficial de Android developers.

Page 26: Contenedores Layout

- See more at: http://androideity.com/2011/07/24/layout-en-android-iii-table-layout/#sthash.tF4VI1gE.dpuf

SCROLLVIEW

uando trabajamos en espacios pequeños como lo son las pantallas de los teléfonos, los desarrolladores debemos poner en práctica algunos trucos útiles para presentar la información al usuario de una forma cómoda, atractiva y práctica sin importar lo limitado que sea el espacio con el que contemos. Uno de estos trucos es el uso del scroll, que nos permite mostrar sólo una parte de la información total que nos interesa mostrarle al usuario y lo que resta se mostrará conforme el usuario se desplace hacia arriba o hacia abajo, según sea el caso.

ScrollView es el contenedor que ofrece una barra de desplazamiento para el contenido que pongamos dentro de él. Es muy útil en los casos en los que el diseño pueda ser demasiado grande para algunas pantallas. La solución será envolver este contenido en un ScrollView, y seguir utilizando la lógica de diseño existentes. Lo que pasará después es que el usuario sólo verá parte del diseño a la vez, y el resto estará disponible a través del desplazamiento.

Realmente es muy sencillo implementarlo, así que pasemos directamente a crear un ejemplo para ver su funcionamiento.

1. Creamos un proyecto llamado AndroideityScrollView utilizando la versión Android 2.1 update 1.

2. Definimos un layout cuyo elemento contenedor será un ScrollView. Dentro de él declararemos una tabla con 7 filas de 200 px cada una. De esta manera tendremos 1400 px en total, un tamaño que nos mostrará cómo es que el scroll nos facilita la vida. A continuación te comparto un trozo de código que deberás escribir dentro del archivo main.xml del directorio res > layout.

Page 27: Contenedores Layout

¿Está incompleto? Como habrás notado, únicamente he puesto parte del código que necesitas para crear el layout completo. La parte que corresponde a <TableRow>…</TableRow> tendrás que copiarla 6 veces más haciendo la variación en el color que gustes ponerle al ejemplo.

3. Corremos el ejemplo y veremos el siguiente resultado:

Habrá veces que dependiendo del tamaño de la pantalla del dispositivo dónde pruebes el demo, algunos serán capaces de mostrar el diseño completo sin necesidad de utilizar el scroll, sin embargo, puede que lo muestre un poco más pequeño que el diseño real. En cambio, cuando utilizamos el elemento ScrollView nos aseguramos que nuestro diseño se

Page 28: Contenedores Layout

muestre del tamaño original y lo único que hará el scroll será particionar la vista que el usuario tendrá del mismo.

Bibliografía

http://androideity.com/2011/07/16/layout-en-android-i-linearlayout/

http://www.sgoliver.net/blog/?p=1341