Explicamos los conceptos básicos de LinearLayout — una ViewGroup básica en Android SDK para alinear elementos secundarios en una sola línea: verticalmente (LinearLayout.VERTICAL) u horizontalmente (LinearLayout.HORIZONTAL). LinearLayout sigue siendo la forma más simple y rápida de construir una fila de botones, una lista de configuraciones o un formulario de entrada cuando la complejidad del diseño no supera los 5–10 elementos. Los atributos layout_weight y orientation gestionan la distribución del espacio y la dirección. Especificación detallada — en LinearLayout API Reference.
Puntos clave
LinearLayout — una de las primeras ViewGroups en Android SDK (API Level 1), diseñada para colocar elementos secundarios secuencialmente en una sola fila o columna. Cada nuevo elemento se posiciona después del anterior, y la dirección se establece mediante el atributo android:orientation. LinearLayout es el contenedor Android más simple y predecible, lo que lo convierte en la elección ideal para interfaces lineales: filas de botones, listas de configuración con icono y texto, menús horizontales.
Históricamente, LinearLayout es la primera ViewGroup que conoce un desarrollador Android principiante. Su ventaja es la transparencia: los elementos secundarios se colocan estrictamente en el orden de declaración, sin reglas de posicionamiento ocultas. A diferencia de RelativeLayout, donde un elemento puede estar vinculado a cualquier vecino, o ConstraintLayout con su sistema de restricciones, LinearLayout funciona según el principio "primero izquierda/arriba, segundo después, tercero después del segundo". Según Google I/O 2017, el 78% de las pantallas en las 1000 aplicaciones principales de Google Play usan LinearLayout como contenedor principal o auxiliar.
La métrica principal de LinearLayout es LinearLayout.MeasureSpec — el sistema de gestión de tamaño. Con orientación VERTICAL, el ancho de cada elemento es igual al ancho del padre (match_parent o fijo), y la altura se determina por el contenido o el atributo. Para HORIZONTAL es al revés: la altura es igual a la del padre, el ancho según el contenido. Si en una fila HORIZONTAL el ancho total de los elementos supera el ancho del padre, los elementos pueden desbordarse de la pantalla (si no se usa weight).
LinearLayout sobrescribe onMeasure y onLayout de ViewGroup. Con orientación VERTICAL, onLayout coloca los elementos a lo largo del eje Y: primer hijo — y=0, segundo — y=prev.bottom + divider.hidden, y así sucesivamente. Con HORIZONTAL — a lo largo del eje X. El Divisor se establece mediante android:divider y android:showDividers (beginning, middle, end). El divisor puede ser un color, drawable o recurso Shape personalizado.
Orientación — un atributo clave de LinearLayout que determina la dirección de colocación de los elementos secundarios. android:orientation="vertical" organiza los elementos de arriba a abajo; android:orientation="horizontal" — de izquierda a derecha (o de derecha a izquierda con localización RTL). Si no se establece la orientación, se usa HORIZONTAL por defecto (en versiones antiguas) — pero la especificación explícita es necesaria para un comportamiento predecible.
android:gravity — alinea el contenido dentro de LinearLayout. Acepta combinaciones: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Un valor de gravity="center" para un diseño VERTICAL centrará todos los elementos horizontalmente. android:layout_gravity — un atributo del elemento secundario que lo alinea dentro del LinearLayout padre. Ejemplo: un botón con layout_gravity="right" en un diseño VERTICAL empujará el botón al borde derecho.
La diferencia: gravity — una propiedad del padre (cómo se organizan los hijos dentro de él), layout_gravity — una propiedad del hijo (cómo se comporta dentro del padre). Confundir estos atributos es uno de los errores más comunes entre los principiantes.
Para diseños HORIZONTAL con elementos de texto (TextView, Button, EditText), es útil android:baselineAligned="true" — alinea todos los textos por la línea base de la fuente, independientemente de su padding, tamaño o altura. Esto hace que una fila con un icono, título y descripción sea visualmente ordenada: el texto no salta arriba y abajo.
layout_weight — un atributo del elemento secundario de LinearLayout que determina qué parte del espacio libre ocupará. Solo funciona en la dirección de orientación (ancho para HORIZONTAL, alto para VERTICAL). Fórmula de cálculo: tamaño = tamaño propio + (espacio libre × (peso del elemento / suma de todos los pesos)). Espacio libre = tamaño del padre — suma de todos los tamaños propios de los hijos.
layout_weight es más eficiente que los tamaños fijos para interfaces adaptativas. Por ejemplo, si el panel izquierdo debe ocupar el 30% de la pantalla y el derecho el 70%, establezca weight=3 y weight=7. Para un funcionamiento correcto, el tamaño en la dirección se establece normalmente en 0dp (android:layout_width="0dp" para HORIZONTAL), entonces el tamaño propio del elemento se considera cero, y el tamaño completo se determina solo por weight. Esta es la recomendación estándar de Google (Android Developers Guide, 2024).
Importante: los pesos se suman para todos los elementos en LinearLayout, incluidos aquellos sin weight establecido (su peso se considera 0). Si un elemento tiene weight=1 y otro tiene weight=2, el primero ocupará 1/3 del espacio libre, el segundo — 2/3. weightSum (un atributo del padre) permite establecer la suma máxima de peso — si los pesos de los hijos suman menos que weightSum, la diferencia queda como espacio vacío.
El formulario de inicio de sesión consta de tres elementos: campo de correo electrónico (ocupa 2/4), campo de contraseña (1/4) y botón (1/4) de la altura de la pantalla. Los tres elementos con weight funcionan solo en orientación VERTICAL por altura.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:hint="Email" />
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:hint="Contraseña"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Iniciar sesión" />
</LinearLayout>
La altura de cada elemento = (parent_height — padding) × (weight / sumWeights). email obtiene 2/4 de la altura, contraseña y botón — 1/4 cada uno. Todos height=0dp, por lo que el tamaño propio no se considera — solo funciona weight.
Un panel con tres botones: icono de retroceso (wrap_content), título (rellenar el resto) e icono de menú (wrap_content). weight para el título = 1, botones sin weight.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical">
<ImageButton
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_arrow_back" />
<TextView
android:id="@+id/toolbar_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Título"
android:textSize="18sp" />
<ImageButton
android:id="@+id/btn_menu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_more_vert" />
</LinearLayout>
Los botones de retroceso y menú ocupan exactamente el espacio necesario para el icono. El título (TextView) con width=0dp y weight=1 se estira a todo el espacio restante entre ellos. gravity="center_vertical" alinea todos los elementos verticalmente centrados.
Una tarjeta de producto: fila horizontal (imagen + bloque de texto vertical). LinearLayout exterior HORIZONTAL, interior — VERTICAL para título, descripción y precio.
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:src="@drawable/product_image"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="12dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nombre del producto"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Descripción breve del producto en dos líneas"
android:textSize="14sp"
android:textColor="@color/gray" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1.299 RUB"
android:textSize="18sp"
android:textColor="@color/accent" />
</LinearLayout>
</LinearLayout>
Imagen a la izquierda (80×80dp), a la derecha — un bloque vertical de tres líneas de texto. El LinearLayout interior tiene weight=1, por lo que ocupa todo el espacio restante después de la imagen. Este es un patrón clásico de tarjeta de lista que se encuentra en miles de aplicaciones.
El principal inconveniente de LinearLayout — la necesidad de contenedores anidados para diseños complejos. Si necesita organizar elementos en una cuadrícula 2×2 o hacer una fila con alineación en ambos bordes, se requieren al menos 2–3 niveles de anidamiento. Cada nivel de LinearLayout añade 2 pases de onMeasure, lo que en dispositivos débiles provoca retrasos notables durante el renderizado.
Según Android Performance Blog (Google, 2017), cada nivel adicional de anidamiento aumenta el tiempo de diseño en 30–50 μs. Para una lista de 20 elementos con 3 niveles de anidamiento, el retraso puede alcanzar 3 ms por elemento — esto es un jank notable durante el desplazamiento. ConstraintLayout resuelve este problema mediante una jerarquía plana, reemplazando 3–4 LinearLayouts anidados con un solo contenedor de restricciones.
Recomendación: use LinearLayout para diseños lineales simples (hasta 10 elementos, un nivel de anidamiento). Para tarjetas de lista, formularios con diferente alineación y pantallas con estructura de tabla, elija ConstraintLayout. Para elementos repetitivos en RecyclerView, use ConstraintLayout en el archivo de diseño del elemento — esto es crítico para el rendimiento del desplazamiento.
Preguntas frecuentes
La razón más común — el tamaño en la dirección no está establecido en 0dp. Para un diseño HORIZONTAL necesita android:layout_width="0dp", para VERTICAL — android:layout_height="0dp". Si el elemento tiene wrap_content o match_parent, weight puede no funcionar o dar resultados inesperados. La segunda razón — weightSum en el padre es menor que la suma de los pesos de los hijos. La tercera — usar match_parent en un elemento hijo en la dirección opuesta.
layout_weight se establece en cada elemento secundario y determina su parte del espacio libre. weightSum — un atributo del LinearLayout padre que establece la suma máxima de pesos. Por defecto, weightSum = suma de todos los layout_weight de los hijos. Si establece weightSum = 3, y los hijos tienen weight=1, cada uno ocupará 1/3. Si solo hay dos hijos con weight=1, el 1/3 restante estará vacío. weightSum es conveniente para fijar proporciones sin recálculo al añadir/eliminar elementos.
Por defecto no hay espacios — los elementos se colocan uno al lado del otro. Si aparecen espacios, verifique: android:divider y android:showDividers en el padre, android:layout_margin en los elementos secundarios. Adicionalmente, android:weightSum puede afectar — si los elementos usan weight, puede quedar espacio vacío entre ellos debido a un cálculo incorrecto. Para espacios cero, establezca todos los márgenes secundarios en 0dp y elimine el divisor.
Para diseños simples unidireccionales (1–5 elementos en una fila/columna) LinearLayout es ligeramente más rápido — no gasta recursos en el cálculo de restricciones. Para diseños complejos (más de 5 elementos, cuadrículas, diferentes tipos de alineación) ConstraintLayout es más rápido porque usa una jerarquía plana en lugar de LinearLayouts anidados. Según las pruebas de Google (Android Performance Blog), ConstraintLayout gana en diseños que requieren 3+ niveles de anidamiento de LinearLayout.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también