contacto[arroba]digitallearning.es
Ejemplo Relative Layout

Interfaces de usuario: layouts

Post Series: Creación de Apps Android: diseño de Interfaz de Usuario

En este tutorial describiremos los diseños o layouts más utilizados para una interfaz de usuario en una Aplicación Android. También explicaremos cómo crearlos, incluyendo algunos elementos, como campos de texto editables y botones, con un sencillo ejemplo práctico.

Para diseñar interfaces de usuario en Android utilizamos una capa (llamada layout), descrita mediante un fichero XML, sobre la que se dispondrán los diferentes elementos gráficos que componen dicho interfaz. Todos estos componentes heredan directa o indirectamente de la clase View.

De forma muy simplificada (y por tanto no muy exacta), XML es un lenguaje que estructura e identifica la información de un fichero en base a etiquetas ((X)HTML sería un ejemplo). Si no sabes lo que es XML, en este tutorial hablamos sobre ello. Al final del mismo tienes también enlaces a páginas donde lo explican, como ésta de la W3C.

Veamos la definición de los términos View y ViewGroup, necesarios para comprender el funcionamiento de la interfaz gráfica en Android:

  • View (o Vista). Esta clase es básica para la creación de todos los componentes usados en la interfaz. Una View ocupa un área rectangular en la pantalla y es el responsable de dibujar los componentes y manejar los eventos que definamos sobre ellos, o dicho de una forma más simple, dibuja los componentes en la pantalla con los que el usuario puede interaccionar.
    Es la clase base para los widgets, que son Views ‘preconstruidas’ que vienen incluidas en la plataforma Android, como los botones, campos de textos, check boxes, radio buttons, etc.
  • ViewGroup (o Grupo de Vista). Hereda directamente de View y se usa para, como su nombre indica, contener y controlar la lista de Views y de otros ViewGroups. Es la clase base para los Layouts, mediante los cuales podemos diseñar una estructura para un conjunto de Views.

El fichero XML que generamos (por ejemplo activity_main.xml) se ubica en la carpeta res/layout, y se carga(*) a través del método setContentView()  en el método onCreate()  de la activity, como veremos en un ejemplo práctico que desarrollaremos en una publicación posterior.

Nota(*): a esta acción del método setContentView también se le suele denominar ‘inflar‘ una vista (view). Más detalle en estas explicaciones  algo más avanzadas (en inglés).

Tenemos dos grandes ventajas al utilizar un fichero XML externo para declarar la UI:

  • Nos permite separar mejor la presentación de nuestra Aplicación Android del código que controla su comportamiento. Esto nos facilita realizar cambios o adaptaciones de dicha interfaz sin necesidad de modificar el código y recompilar de nuevo, pudiendo crear layouts XML por ejemplo para distintas orientaciones o tamaños de pantalla.
  • Es más fácil visualizar y entender la estructura del layout en un fichero XML que podemos leer sin mucha dificultad. Esto nos facilita también las tareas de depuración.

En cualquier caso, también es posible construir la interfaz de usuario utilizando únicamente código. Lo veremos también en ese proyecto ejemplo que desarrollaremos más adelante, creando dos versiones del mismo interfaz, uno usando fichero XML y otro solo basado en código..

Antes de empezar a describir distintos tipos de layouts y algunos de los elementos que podremos agregarle (TextView, EditText, Button) utilizándolos en un ejemplo de interfaz que realizaremos en cada uno de esos layouts, vamos a mencionar dos aspectos importantes:

Identificación

Hay un atributo muy importante, android:id, que debemos tener presente siempre, tanto para los Layouts como para los elementos gráficos. Mediante este atributo, podremos identificar a cada elemento para luego acceder a ellos desde el código o para posicionarlos de manera relativa como veremos en el RelativeLayout. Es por tanto muy recomendable asignarles siempre un identificador (id).

Para asignarles un id nuevo, usaremos la siguiente sintaxis: android:id=@+id/botonaceptar , en la que hemos creado un nuevo id llamado botonaceptar. Si en cambio queremos referirnos a un id ya creado, el carácter “+” sobra, quedando @id/boton_aceptar .

Unidades de medidas

Otra consideración a tener muy en cuenta es que, al existir tanta diversidad de dispositivos Android, es conveniente usar siempre medidas relativas al tamaño de pantalla de cada uno. Esto lo podemos hacer usando:

  • La medida dip (density-independent pixel ó dp, que al caso es la misma), recomendada para especificar el tamaño de los views en nuestro layout (siendo 160dp el equivalente a una pulgada (2,54 cm) de pantalla física)
  • La medida sp (scaled-independent pixel), similar a dp y recomendada para definir tamaños de fuentes.

Layout

Los Layouts son los elementos sobre los cuales se sustentan los diferentes componentes de la interfaz de usuario, y controlan la distribución, la posición y las dimensiones de dichos componentes. Es decir, un layout define la estructura o diseño del UI.

Para poder implementar cualquiera de estos elementos para la distribución visual de la aplicación, bastará con seleccionarla en la ventana “Palette“, y añadirlo al árbol de componentes en la ventana “Design“.

A continuación describiremos diferentes tipos de Layouts muy comunes, con un ejemplo simple de diseño basado en cada uno.

FrameLayout

Es el más simple de todos. En él, todos los elementos se alinean teniendo en cuenta la esquina superior izquierda de la pantalla, no pudiendo ser ubicados en otro lugar, por lo que se colocarían unos encima de otros tapando completa o parcialmente a los demás, a menos que el nuevo elemento sea transparente. Por esta razón, se usa normalmente para mostrar un único elemento, ya que puede resultar difícil organizar la posición de los elementos, o bien una serie animada de imágenes donde cada una se va posicionando sobre la anterior.

Los elementos incluidos en este layout han de tener los atributos android:layout_width y android:layout_height, que podrán tomar los valores:

  • match_parent (fill_parent) si lo que se quiere es que se tome la dimensión completa del padre
  • wrap_content, si se desea que tome la dimensión de su contenido.

A partir de la versión 8 de la API de Android, el valor fill_parent fue renombrado a match_parent, por lo que aún nos podemos encontrar con uno u otro. Se permiten ambos, aunque se recomienda match_parent.

Si queremos posicionar los elementos de otra forma, deberíamos de “jugar” con los atributos android:layout_gravity (especifica como la vista hijo (child view) debe posicionarse en su contenedor) y con las destinadas a controlar los márgenes y alineaciones, como android:layout_marginTop, android:layout_marginLeft, android:layout_alignParentLeft, etc…

Veamos un ejemplo de cómo quedaría una interfaz con FrameLayout:

Ejemplo Diseño Frame Layout

y del fichero XML que lo describe, donde vemos cómo se definen los diferentes componentes: TextView (“Datos del curso”), tres EditText (“Nombre”, “Duración”, “Curso”) y un Button (botón “Enviar”):

Este fichero XML es generado automáticamente por Android Studio al utilizar su editor visual de creación de interfaces.Si alguna vez has creado páginas Web con un editor WYSIWYG tipo KompoZer o DreamWeaver, es algo similar: compones gráficamente la página y se genera el código HTML acorde a esos elementos y disposición.

LinearLayout

Este layout alinea los elementos en una única dirección, que puede ser vertical u horizontal, dependiendo del valor que le demos al atributo android:orientation. Todos los elementos aparecerán uno detrás de otro, sin solaparse entre ellos, como ocurría con el FrameLayout. El LinearLayout respeta los márgenes entre los elementos hijos y su gravedad dentro de la pantalla (ésta puede ser a la derecha, a la izquierda o en el centro).

En este layout, al igual que en el anterior, los elementos hijos deben establecer sus atributos android:layout_height y android:layout_width para determinar sus dimensiones dentro del layout, aunque en este caso dispondremos de otro atributo llamado android:layout_weight. Este atributo permite que un elemento se expanda para llenar cualquier espacio que quede libre. Por defecto este valor es 0, es decir, no se expande.

Pongamos un ejemplo. Si agregamos dos cuadros de texto, según los valores que pongamos a este atributo, tendremos:

  • Si a uno se le da el atributo de android:layout_weight=”1”, sucede que entre los dos cuadros de texto se ocupa toda la pantalla, uno de ellos permanecerá en su tamaño normal y al que le hemos asignado el atributo android:layout_weight ocupará el resto de la pantalla.
  • Si le hubiéramos asignado a los dos este atributo igual a 1, cada uno ocuparía la mitad de la pantalla.
  • Si le hubiéramos dado a uno el valor 2 y al otro le hubiéramos dado el valor 1, entre los dos ocuparían también toda la pantalla pero uno de ellos tendrá el doble de altura/anchura que el otro.

El layout genérico creado con un LinearLayout tendría este diseño:

Linear Layout

Ahora vamos a realizar el mismo ejemplo que hicimos en el layout anterior (TableLayout)  en este caso con un LinearLayout con orientación horizontal:

Ejemplo Linear Layout horizontal

y el fichero XML que lo describe:

TableLayout

En este layout, los elementos hijos se distribuyen de forma tabular, como si de una tabla se tratara, definiendo las filas y columnas necesarias, y la posición de cada elemento dentro de la tabla.
Para definir una fila, se usa el objeto TableRow, y dentro de éste se van agregando los elementos que compondrá la fila, sin necesidad de definir un objeto columna. De este modo, la tabla vendrá definida por tantas filas como objetos TableRow hayamos insertado, y tantas columnas como elementos que hayamos insertado en cada TableRow.

Vemos un diseño genérico, con la disposición de los elementos en este formato de tabla:

Table Layout

Ahora veamos el ejemplo que estamos utilizando en los otros layouts,  con controles ya implementados en un LayoutTable:

 

Table Layout diseño

El fichero XML que describiría este ejemplo sería:

RelativeLayout

Este layout permite que los elementos se dispongan en la pantalla de forma relativa al elemento padre o a cualquier otro elemento agregado al layout, por lo tanto, podríamos hacer cosas como alinear dos elementos a la derecha, o crear uno debajo del otro, centrarlos en la pantalla, a la izquierda, etc.

Veamos también un ejemplo de uso de este layout, usando los mismos elementos que en los casos anteriores.

Relative Layout

Ejemplo Relative Layout

y el fichero XML correspondiente:

GridLayout

Layout que define un diseño situando a sus hijos en una forma de rejilla rectangular.

Dicho grid o rejilla se compone de un conjunto de líneas que separan el área de visualización de las celdas. Las líneas de cuadrícula son referenciadas por índices. Un grid con N columnas tiene n + 1 índices del grid que van de 0 a N, ambos inclusive.

En el siguiente ejemplo, puedes comprobar cómo quedaría esta forma de distribución de los controles:

Ejemplo diseño Grid Layout

Layouts para contenido dinámico

Cuando el contenido que mostramos en el layout no esta predeterminado y se genera dinámicamente, por ejemplo como resultado de una consulta a una base de datos, podemos utilizar un adaptador que hace de intermediario entre el layout y el contenido, insertando éste último en formas de vistas en el layout.

Vemos dos ViewGroups que utilizan esta técnica que nos aparecen en el Panel de Diseño de Android Studio en la sección ‘Containers’ (contenedores):

ListView

Un ListView es un ViewGroup que muestra una lista de elementos desplazables. Los elementos o items de la lista se insertan automáticamente en ella utilizando un adaptador que extrae el contenido de una fuente tal como una matriz o una consulta a una base de datos y convierte cada item en una vista que se coloca en la lista.

List View

GridView

Un GridView es un ViewGroup que muestra los elementos en una rejilla de dos dimensiones desplazable. Los elementos de cada cuadrícula se insertan automáticamente usando un ListAdapter.

Grid View

Avanzado: en series dedicada a controles de selección en una UI vimos en un proyecto ejemplo la implementación de un ListView y un GridView extrayendo datos de una base de datos y la creación de una ListView personalizada

En el próximo tutorial continuaremos con los detectores de eventos que nos permiten capturar las interacciones del usuario con los componentes de la interfaz.


Créditos/Documentación: parte de este tutorial está basado en la documentación oficial publicada por Android Developers con licencia Creative Commomns Attribution 2.5, de donde también provienen las imágenes-croquis de los distintos layouts.

 


 

This Post Has One Comment

Comments are closed.