Programación Android, LinearLayout

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0

Como ya se ha dicho, un 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 una fila, uno detrás de otro. Para indicar si se ordena en forma de filas o de columnas lo hacemos a través de su propiedad android:orientation, que admite valores “horizontal” y “vertical”.

Para la buena configuración de un contenedor LinearLayout debes conocer seis conceptos que ayudan a definir el aspecto visual del mismo: la orientación (orientation), tamaño (fill model), el peso (weight), el relleno (padding), el margen (margin) y la gravedad (gravity) definidos en la clase LinearLayout.LayoutParams.

Orientación (orientation):

La orientación (orientation) nos ayudará a indicar si el LinearLayout representa una columna o una fila. Para definirla, hay que agregar una propiedad android:orientation en el elemento del XML, y los valores que podemos escribir son “horizontal” o “vertical”. Si se establece horizontal trabajaremos con un layout a modo de filas, mientras que si lo establecemos como vertical, lo trabajaremos a modo de columnas.
También hay que saber que la orientación puede ser modificada en tiempo de ejecución utilizando “setOrientation()” de la clase LinearLayout, pasando como parámetro HORIZONTAL o VERTICAL según sea el caso.

Tamaño(width, height):

Para comprender este concepto vamos a guiarnos por un ejemplo. Supongamos que tenemos una serie de botones. Cada uno de estos botones tiene un tamaño natural basado en el largo del texto que contienen. La combinación de cada uno de los tamaños de los botones 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:

  • Se puede 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.
  • Se puede utilizar 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.
  • Por último, se puede utilizar el valor fill_parent (hasta la API 8) o match_parent (API 8 y superiores), que indica que el elemento es libre de utilizar todo el espacio disponible del contenedor en el que se encuentra.

Comúnmente, se utilizará 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 de la aplicación.

Peso (weight)

LinearLayout tiene a repartir el espacio disponible de forma uniforme entre las vistas que tiene que distribuir, asignando un tamaño similar a cada una de ellas (aunque teniendo en cuenta las restricciones que la propia vista imponga).
El peso permite variar este comportamiento, asignando a cada vista un nivel de “importancia” que se traduce en más o menos espacio ocupado en el resultado final, de forma proporcional al valor asignado. El atributo que se utiliza para ello es android:layout_weight. Esta propiedad indica la proporción del espacio libre que le corresponde a un 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 asignamos pesos 1, 2 y 3 a tres vistas, LinearLayout tratará de asignar la mitad del espacio disponible a la que tiene peso 3 (3 es la mitad de la suma total de esos pesos, que es 6 en este ejemplo). De forma similar, la otra mitad del espacio libre la repartirá entre otras dos visitas tratando de usar el doble para la que tiene peso 2.
Hay que tener en cuenta que el reparto no es exacto. Incluso si la vista no incluye ninguna restricción especial, como android:minWidth, su contenido puede afectar al espacio que se le asigne finalmente. Android siempre tratará de conseguir la mejor visualización posible para cada vista, aunque tenga que incumplir ligeramente alguna de las restricciones que pongamos.
El valor del peso es de tipo float, por lo que podemos utilizar decimales si queremos más precisión.
No es necesario que la suma de los pesos sea 1. Los pesos pueden ser sumar cualquier cantidad salvo que se utilice la propiedad android:weightSum de LinearLayout. En ese caso, la suma no podrá superar la cifra que se especifique. Esto puede servir para determinar la proporción que ocupa una vista sin asignar peso a las demás. Por ejemplo, si la suma se establece a 1 y se asigna a un peso de 3,3, la vista ocupará el 30% del espacio.

Relación del peso (weight) y el tamaño (size)

La correcta distribución de un LinearLayout dependerá de la combinación que hagamos del weight con el width, o con el height según la orientación que estemos utilizando en un contenedor del tipo LinearLayout.
Cuando se definen las propiedades width y height al valor WRAP_CONTENT, independientemente al valor que le hayamos asignado al peso si el ancho que puede ocupar cada botón influye en la distribución, no tiene en cuenta la propiedad del peso..
WeightEnAndroid_05

El punto clave para entender este comportamiento es que el layout toma el espacio libre que queda después de distribuir los elementos y de ahí le resta por ejemplo al tercer botón espacio porque es excesivo para lo que necesita para mostrarse, y se lo brinda al primer botón que requiere más espacio.
Para obtener el resultado deseado, el valor para el layout_width de los tres botones se debe definir a 0dp. Eso nos ayuda a decirle a nuestro diseño que resalte la propiedad del peso y pueda distribuir equitativamente los componentes sin importar lo extenso del contenido que tenga cada celda, tal y como si se trataran de porcentajes. Por esa razón, aunque el primer botón tenga el texto más largo, se adapta al peso definido que en proporciones es igual al 25% del espacio total de su contenedor padre.
linearlayout-logic_exp

Gravedad (gravity)

Hay un parámetro que nos permite controlar el alineamiento de las vistas contenidas en el diseño: la gravedad. Este parámetro, definido en LinearLayout.LayoutParams, y que se corresponde con el atributo android:Layout_gravity no es exclusivo de LinearLayout, FrameLayout también lo proporciona y, por herencia también TableLayout, TableRow e incluso RadioGroup. Los valores disponibles para el parámetro y el resultado obtenido con cada uno de ellos son comunes para todos estos diseños, por lo que les será de aplicación en los demás Layout.
Por defecto, 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 en el archivo XML o desde el código Java con el método setGravity(). Al atributo android:layout_gravity se le asigna una cadena de texto que contiene uno o más de estos valores. Si hay más de uno se deparan mediante |. Para cada uno de estos valores existe una constante de igual nombre que se puede utilizar para asignar la gravedad mediante código Java. De forma similar, si en Java se usa más de una constante, se agregan mediante el operador lógico |:

  • top y bottom:: alinean el borde superior/inferior de la vista con el del área útil del diseño, sin alterar el tamaño de la vista.
  • left y right: alinean el borde izquierdo/derecho de la vista con el del área útil del diseño, sin alterar el tamaño de la vista.
  • center_horizontal y center_vertical: centran la vista horizontal o verticalmente en el área útil del diseño sin alterar su tamaño.
  • center: centra la vista vertical y horizontalmente, de forma simultánea, en el área útil del diseño sin alterar su tamaño.

Gravedad del propio Layout

La propiedad android:gravity o desde el código Java con el método setGravity() permite definir la gravedad del propio LinearLayout, es decir, cómo se alinea todo su contenido. Afecta al conjunto de las vistas que se incluyen en él, pero no al contenido de las propias vistas. Para que afecte al contenido de las vistas habría que especificar el atributo android:gravity dentro de cada widget.

Relleno(padding)

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.
Por defecto, 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 de Java en tiempo de ejecución con el método setPadding() de LinearLayout.
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 android:paddingLeft, android:paddingRight, android:paddingTop y android:paddingBottom.
Para definir el valor de este atributo hay una serie de unidades de medida que se pueden utilizar (dp, sp, pt, px, mm, in).

Margen (margin)

Los márgenes son externos a la vista a la que se le aplican. Por lo tanto no son propiedades de la clase View como ocurre con el padding. En lugar de eso, son parámetros de los diseños.
Dentro de la clase ViewGroup se define otra clase con parámetros, se trata de la clase MarginLayoutParams. Esta clase hereda a su vez de ViewGroup.LayoutParams. Las clases de parámetros que se definen en los diseños heredan (directa o indirectamente) de esta clase MarginLayoutParams De esta forma se agregan los márgenes a los parámetros básicos que comparten todos los diseños.
Al igual que con el resto de parámetros de diseño, los atributos XML correspondientes se aplican sobre las vistas contenidas en el diseño como si fueran propiedades propias. Y, de igual forma, los atributos de MarginLayoutParams también se distinguen mediante el prefijo layout_.
Para establecer los márgenes de cada vista la clase MarginLayoutParams proporciona los atributos android:layout_marginLeft, android:layout_marginRight, android:layout_marginTop y android:layout_marginBottom. Al igual que con el padding, estos atributos permiten establecer valores de margen diferentes para cada lateral de la vista. También en este caso tenemos un atributo android:layout_margin que permite establecer el mismo valor para el margen de los cuatro laterales a la vez.
Siguiendo con las similitudes, la clase MarginLayoutParams proporciona un método setMargins que permite asignar valores a los márgenes de los laterales izquierdo, superior, derecho e inferior de la vista.

Línea base (baselineAligned)

Otra característica a tener en cuenta es la línea base. De forma predeterminada, LinearLayout alinea las vistas que contiene en función de su línea base (línea invisible sobre la que apoya el texto). Esto permite que un TextView y un Button queden alineados verticalmente de forma natural en un diseño horizontal. La propiedad android:baselineAligned o desde el código Java setBaselineAligned() permite modificar este comportamiento, cuando en algunos casos puede dar problemas. Establecer esta propiedad a false desactiva este alineamiento.

Share if you like...Share on Facebook0Tweet about this on TwitterShare on Google+0Share on LinkedIn0
The following two tabs change content below.
Reborn as IT Developer. Desarrollador Android y fundador de Proyecto Simio. "En realidad, yo no puedo enseñar nada a nadie, sólo puedo hacerles pensar." - Sócrates.

2 thoughts on “Programación Android, LinearLayout

    1. Muchas gracias Manux, la intención del blog es ayudar a aquellos que quieren iniciarse en la programación, en este caso en Android, así que el que sea de utilidad para la gente me alegra mucho :)

      Un saludo.

Deja un comentario