29. Android: tipos de layouts

Uno de los elementos de los que estan compuestas la interfaces de usuario en Android son los "layouts".

Los "layout" son elementos invisibles de la interfaz de usuario. En realidad son como un contenedor que establece la manera en que se dispondrán los elementos que coloquemos en su interior.

Por lo general, cada interfaz de usuario tendrá un "layout" que actuará como contenedor general de toda nuestra interfaz, es decir, englobando al resto de los elementos que la componen.

Los tipos de "layouts" que podemos añadir a nuestras interfaces de usuario son los siguientes:
  • LinearLayout
  • TableLayout
  • RelativeLayout
  • AbsoluteLayout
  • FrameLayout
  • ConstraintLayout
  • GridLayout
Los veremos en detalle cada uno de ellos en este mismo artículo.


El "layout" por defecto de la interfaz de usuario

Como ya hemos visto anteriormente, cuando creamos un nuevo proyecto Android, se genera un archivo XML para la interfaz de usuario llamado "activity_main.xml".

Si abrimos dicho archivo desde el explorador de archivos de Android Studio (ruta "res" > "layout"), y acudimos al arbol de componentes, veremos esto:


Como se puede apreciar en la imagen, el tipo de "layout" que tiene el archivo "activity_main.xml" es de tipo "ConstraintLayout". En el interior de este "ConstraintLayout", hay un elemento de tipo "TextView".

Reemplazar la interfaz de usuario por defecto

Como ya sabemos, cualquiera de los elementos que se generan por defecto en la interfaz de usuario se pueden eliminar, para poder crear nosotros una nueva interfaz en base a los requerimientos de la aplicación.

Si nuestra nueva interfaz va a estar basada en otro tipo layout (por ejemplo un "LinearLayout"), es aconsejable que eliminemos primeramente los elementos que ahi en su interior, ya que algunos de los atributos de dichos elementos están relacionados con el "ConstraintLayout" (marco rojo):



Como ya sabemos desde el "arbol de componentes" por ejemplo, es posible eliminar elementos pulsando con el botón derecho sobre un elemento y seleccionando "Delete". Hasta ahí, todo bien, pero si intentamos hacer esto mismo en el "layout" general de nuestra interfaz (ConstraintLayout) comprobaremos que no desaparece. Es decir, no es posible eliminar el "layout" general de nuestra interfaz desde el arbol de componenentes.




Por tanto, en vista de que no es posible eliminarlo, vamos a reemplazarlo. Para ello acudimos a la vista "Text" donde está el código XML, y reemplazamos el texto "ConstraintLayout" de la primera etiqueta XML por el texto cualquier otro tipo de layout, por ejemplo "LinearLayout":



Si ahora acudimos a la vista "Design" veremos que el arbol de componentes el tipo de layout ha cambiado también:


Crear un nuevo archivo de "layout"

Cuando creamos un nuevo proyecto, se genera un archivo de layout, pero además es posible crear otros archivo de layout. Para ellos vamos a la carpeta "res > layout" que está en la ruta. Despues, pulsamos botón derecho sobre "layout" y elegimos "New > XML (abajo del todo) > Layout XML file". A continuación, aparecerá un cuadro de dialogo donde se le da nombre al nuevo archivo, y ademas (en el segundo campo) se establece el tipo de "layout" principal que tendrá el archivo: LinearLayout, TableLayout, ConstraintLayout, etc.

LinearLayout


El "LinearLayout" es uno de los "layouts" más fáciles de usar. Se caracteriza porque cuando introducimos elementos en su interior, simplemente se colocan uno a continuación del otro.

Hay dos tipos de "LinearLayout":
  • Horizontal: los elementos internos se colocan uno debajo de otro (opción por defecto).
  • Vertical: los elementos internos se colocan uno a la derecha del anterior.


Para comprobar el resultado que ofrecen las 2 opciones vamos a añadir 3 elementos "TextView" en el interior del "LinearLayout".


Para añadir un elemento TextView, pinchamos y arrastramos sobre el elemento TextView dentro de la paleta, y dejamos caer el elemento sobre el arbol de componentes en el interior del "LinearLayout" (recomendado), o lo dejamos caer en el area de visualización del interfaz.

El resultado no es algo "esperado", ya que los 3 "TextView" se están posicionando uno encima de otro:


Para que no se visualicen así, tendremos que añadir el atributo "orientation=vertical" en la etiqueta "LinearLayout" del código XML:



El resultado será este (más esperado que el anterior..):


Y el resultado será este si escribimos "orientation=horizontal" en vez de "orientation=vertical":






Vemos que cuando establecemos la "position=horizontal" es como si los elementos flotasen a la izquierda (CSS). Y cuando ponemos position "vertical" es como si los elementos ocupasen en "realidad" el 100% del contenedor (elementos de bloque CSS).

Podemos cambiar la orientación (de vertical a horizontal y viceversa) del "LinearLayout", clicando sobre el botón que aparece en el centro de la siguiente imagen:





Por lo general, la orientación que más vamos a usar es la vertical, puesto que en general querremos que nuestros elementos estén uno debajo del otro.

Ancho y alto de los elementos

 La disposición de los elementos también va a depender de otros 3 factores:
  • layout_width: es el ancho del elemento.
  • layout_height: es el alto del elemento.
  • layout_weight: es la proporción que ocupa el elemento.
Los 2 primeros indican el ancho y el alto del elemento respectivamente. Para ajustar el valor de ambas propiedades en un elemento, pulsamos sobre el elemento y en el panel de propiedades se muestran las dos propiedades:




Si desplegamos el "select" de cada uno, veremos que aparecen estas las opciones "match_parent" y "wrap_content":



  • match_parent: el elemento ocupará el 100% del ancho/alto del elemento contenedor (display: block en CSS).
  • wrap_content: el elemento ocupa lo que ocupa su contenido (display: inline en CSS).
Vamos a probar a cambiar el valor de alguno de estos valores, para ver que resultado producen. Por ejemplo:

Caso 1. Si establecemos "orientation: horizontal"  y cambiamos el valor del primer "TextView" a "layout-width: match_parent", se produce esto:


Lo que ha ocurrido es que el primer "TextView" ocupa el 100% del ancho del contenedor, con lo que el segundo y el tercero "TextView" quedan escondidos a su derecha y no aparecen en la interfaz.

Caso 2:

Si queremos que vuelvan aparecer el segundo y el tercero, vamos a modificar la propiedad "layout_weight" del primer TextView, dandole valor "1":



Si además establecemos el mismo valor para dicha propiedad en el segundo y el tercer TextView, y ademas les asignamos el valor "match_parent" a la propiedad "layout_width", obtendremos algo tal que esto:




TableLayout

Este "layout" puede ser el más conveniente en el caso de que el contenido de nuestra interfaz esté tabulado.

En un "TableLayout" no podemos añadir directamente otros elementos, sino añadimos previamente un layout "TableRow" ("fila de tabla"):







Veamos que ocurre si alargo uno de los textos de una celda, en concreto el de la segunda celda de la la primera fila:


Como vemos, el ancho de la segunda celda de la segunda fila también ha cambiado.


Cambiar el ancho de las columnas

Como vemos, el ancho de las celdas no se distribuye a lo largo de la fila, ya que las celdas miden lo que mide el texto de dentro.

Podemos hacer que el ancho de las celdas se extienda a través de la propiedad "stretchColumns" ("estirar columnas"):


Con el código anterior, la 1ª columna (0), se estirará todo lo que le permita el contenedor donde está situada la tabla, en este caso el contenedor es la interfaz de usuario. El resultado es este:





También es posible estirar varias columnas:




En este caso estamos estirando la primera (0) y la tercera columna (2) todo lo que de de si el contenedor. Como estamos estirando dos columnas se reparte el espacio entre las dos a partes iguales:



Ejercicio: hacer que las 3 columnas midan el mismo ancho.

Hacer que una celda ocupe dos columnas

También, es posible hacer que una celda ocupe dos columnas, del mismo modo que hacíamos con el atributo "colspan" en las tablas de HTML. Por ejemplo, si queremos unir la 1ª y la 2ª celda de la 1ª fila, lo primero que tenemos que hacer eliminar eliminar la 2ª celda de la 1ª fila, y despues añadimos el atributo "layout_span=2" a la 1ª celda de la 1ª fila.




El resultado es este:




Hacer que las celdas ocupen una determinada proporción del ancho

Si queremos que una columna se expanda pero ocupando una derminada parte del ancho total del contenedor, deberemos de asignar un valor a la propiedad "layout_weight" de un "TextView". Por ejemplo, si queremos que la 1ª y la 2ª columna ocupen la mitad de la tabla, y la 3ª la otra mitad, ponemos esto


Deberemos añdir además el siguiente valor a "layout_width" a cada uno de los "TextView":


El resultado es este:


Ejercicio: crear un formulario usando "TableLayout".



RelativeLayout


Los elementos se colocan de manera relativa a su elemento contenedor RelativeLayout o de manera relativa a la posición de los elementos hermanos.

En este tipo de "layout" es más habitual el uso del ratón (pinchar y arrastrar) que en otros tipos de "layout", para cambiar las coordenadas XY del elemento.

En este caso, vamos a empezar por añadir un elemento "TextView" en en el ángulo superior izquierdo del area de previsualización.


Si vamos al código XML vemos que es este:


Ahora vamos a arrastrar el "TextView" hasta el ángulo superior derecho.


Si acudimos de nuevo al código XML vemos lo siguiente:


Como se puede ver se han añadido una serie de atributos al elemento "TextView" que indican la posición del "TextView" con respecto al contenedor "RelativeLayout".

Ahora desplacemos el "TextView" a la parte derecha a media altura, veremos que aparece.

Aunque podemos situar un elemento libremente en cualquier cordenada XY, el RelativeLayout tiene una serie de puntos de anclaje, de manera que independientemente del tamaño de la pantalla, el elemento permanece en la misma posición relativa.

Estos son los puntos de anclaje de un elemento con respecto a un "RelativeLayout":

Puntos de anclaje dentro de un RelativeLayout




Inconveniente: si situamos el elemento en alguna posición que NO sea un punto de anclaje y redimensionamos el area de previsualización, veremos que el elemento NO se resitua manteniendo las distancias con los 4 lados.




Añadir un nuevo elemento


Veamos ahora que pasa si ahora añadimos un nuevo elemento a nuestra interfaz, por ejemplo otro "TextView", y lo arrastramos veremos que, además de poder posicionarlo con respecto al "RelativeLayout" lo podemos posicionar con respecto al primer "TextView" porque son hermanos.

Entre dos elementos que son hermanos se crean una relación de dependencia, de manera que cuando uno se mueve (jefe), el otro (esclavo) de desplaza donde vaya el primero.



En este caso, los elementos ocupan por defecto el espacio que ocupa su contenido pero es posible modificarlo (como hacíamos en "LinearLayout") a través de las propiedades "layout_width" y "layout_height".


ConstraintLayout

Es un versión mejorada del "RelativeLayout".

Al añadir un elemento a un RelativeLayout veremos que podemos moverlo libremente por el area de previsualización, no hay puntos de anclaje ni si quiera.

Si seleccionamos el elemento con el ratón, vemos que aparecen unos circulos blancos alreadedor del elemento:



Mediante el uso de "ConstraintLayout" podremos añadir una especie de muelles a nuestro elementos. Los "muelles" permiten que independientemente de la resolución del dispositivo, las distancias con respecto a otros elementos sean proporcionales.

Para sacar esos muelles clicamos sobre los circulos blancos y lo arrastramos. El circulo de arriba lo vamos a arrastrar hasta el margen superior del area de previsualización. OJO: no nos debemos de preocupar si al crear el primer "muelle", el objeto se desplaza. Cuando coloquemos los otros muelles el objeto volverá su posición correcta. Una vez que hemos creado los 4 muelles, se ve lo siguiente:



Si ahora redimensionamos el area de previsualización veremos algo así:


Como vemos las distancias con los 4 lados se han mantenido de manera proporcional. Es decir que si colocamos el elemento en el margen izquierdo a media altura, tal que así:


aunque la altura del dispositivo cambie, el elemento siempre va a estar a media altura (como si tuviese un punto de anclaje).

También es posible controlar todo los relativo a los muelles del elemento y algunas propiedades más, a través de un esquema que se puede encontrar en el panel del propiedades:




  • Si movemos el elemento, veremos que los valores que los "sliders" (vertical y horizontal) también se modifican.

  • Si pulsamos sobre los puntos azules, podemos eliminar los "muelles", y si volvemos a pulsar sobrel el circulo con signo "+" el muelle vuelve a aparecer.

  • Si pulsamos varias veces sobre los simbolos (>>>) podemos cambiar el tamaño (ancho y alto) del elemento ("wrap_content", "match_parent", o un ancho/alto fijo). Al pulsar en este simbolo, veremos que hay 3 estados. veremos que en la parte superior izquierda del cuadrado aparece una linea diagonal. Si pulsamos sobre ella cuando estemos cambiando el alto del elemento, podremos cambiar el "aspect-ratio" del elemento, por ejemplo si ponemos 1:2, el alto del elemento sera 2 veces el ancho.

























Comentarios

Entradas populares de este blog

5. CSS: formatear un documento HTML

34. Java: final, static, constantes, colecciones