Explicamos os conceitos básicos do LinearLayout — uma ViewGroup básica no Android SDK para alinhar elementos filhos em uma única linha: verticalmente (LinearLayout.VERTICAL) ou horizontalmente (LinearLayout.HORIZONTAL). O LinearLayout continua sendo a forma mais simples e rápida de construir uma fileira de botões, uma lista de configurações ou um formulário de entrada quando a complexidade do layout não ultrapassa 5–10 elementos. Os atributos layout_weight e orientation gerenciam a distribuição do espaço e a direção. Especificação detalhada — em LinearLayout API Reference.
Principais pontos
LinearLayout — uma das primeiras ViewGroups no Android SDK (API Level 1), projetada para posicionar elementos filhos sequencialmente em uma única linha ou coluna. Cada novo elemento é posicionado após o anterior, e a direção é definida pelo atributo android:orientation. LinearLayout é o contêiner Android mais simples e previsível, tornando-o a escolha ideal para interfaces lineares: fileiras de botões, listas de configurações com ícone e texto, menus horizontais.
Historicamente, o LinearLayout é a primeira ViewGroup que um desenvolvedor Android iniciante conhece. Sua vantagem é a transparência: os elementos filhos são posicionados estritamente na ordem de declaração, sem regras de posicionamento ocultas. Ao contrário do RelativeLayout, onde um elemento pode ser vinculado a qualquer vizinho, ou do ConstraintLayout com seu sistema de restrições, o LinearLayout funciona no princípio "primeiro esquerda/topo, segundo após ele, terceiro após o segundo". De acordo com o Google I/O 2017, 78% das telas nos 1000 principais aplicativos do Google Play usam LinearLayout como contêiner principal ou auxiliar.
A métrica principal do LinearLayout é LinearLayout.MeasureSpec — o sistema de gerenciamento de tamanho. Com orientação VERTICAL, a largura de cada elemento é igual à largura do pai (match_parent ou fixa), e a altura é determinada pelo conteúdo ou atributo. Para HORIZONTAL é o oposto: a altura é igual à do pai, a largura pelo conteúdo. Se em uma linha HORIZONTAL a largura total dos elementos exceder a largura do pai, os elementos podem transbordar para fora da tela (se não usar weight).
LinearLayout sobrescreve onMeasure e onLayout da ViewGroup. Com orientação VERTICAL, onLayout posiciona os elementos ao longo do eixo Y: primeiro filho — y=0, segundo — y=prev.bottom + divider.hidden, e assim por diante. Com HORIZONTAL — ao longo do eixo X. O Divisor é definido via android:divider e android:showDividers (beginning, middle, end). O divisor pode ser uma cor, drawable ou recurso Shape personalizado.
Orientação — um atributo chave do LinearLayout que determina a direção do posicionamento dos elementos filhos. android:orientation="vertical" organiza os elementos de cima para baixo; android:orientation="horizontal" — da esquerda para a direita (ou da direita para a esquerda com localização RTL). Se a orientação não for definida, HORIZONTAL é usado por padrão (em versões antigas) — mas a especificação explícita é necessária para um comportamento previsível.
android:gravity — alinha o conteúdo dentro do LinearLayout. Aceita combinações: top, bottom, left, right, center, center_horizontal, center_vertical, fill, clip_vertical, clip_horizontal. Um valor de gravity="center" para um layout VERTICAL centralizará todos os elementos horizontalmente. android:layout_gravity — um atributo do elemento filho que o alinha dentro do LinearLayout pai. Exemplo: um botão com layout_gravity="right" em um layout VERTICAL empurrará o botão para a borda direita.
A diferença: gravity — uma propriedade do pai (como os filhos são organizados dentro dele), layout_gravity — uma propriedade do filho (como ele se comporta dentro do pai). Confundir esses atributos é um dos erros mais comuns entre iniciantes.
Para layouts HORIZONTAL com elementos de texto (TextView, Button, EditText), android:baselineAligned="true" é útil — ele alinha todos os textos pela linha base da fonte, independentemente de padding, tamanho ou altura. Isso torna uma linha com ícone, título e descrição visualmente organizada: o texto não pula para cima e para baixo.
layout_weight — um atributo do elemento filho do LinearLayout que determina qual parte do espaço livre ele ocupará. Funciona apenas na direção da orientação (largura para HORIZONTAL, altura para VERTICAL). Fórmula de cálculo: tamanho = tamanho próprio + (espaço livre × (peso do elemento / soma de todos os pesos)). Espaço livre = tamanho do pai — soma de todos os tamanhos próprios dos filhos.
layout_weight é mais eficiente que tamanhos fixos para interfaces adaptativas. Por exemplo, se o painel esquerdo deve ocupar 30% da tela e o direito 70%, defina weight=3 e weight=7. Para funcionamento correto, o tamanho na direção geralmente é definido como 0dp (android:layout_width="0dp" para HORIZONTAL), então o tamanho próprio do elemento é considerado zero, e o tamanho inteiro é determinado apenas pelo weight. Esta é a recomendação padrão do Google (Android Developers Guide, 2024).
Importante: os pesos são somados para todos os elementos no LinearLayout, incluindo aqueles sem weight definido (seu peso é considerado 0). Se um elemento tem weight=1 e outro tem weight=2, o primeiro ocupará 1/3 do espaço livre, o segundo — 2/3. weightSum (um atributo do pai) permite definir a soma máxima de peso — se a soma dos pesos dos filhos for menor que weightSum, a diferença permanece como espaço vazio.
O formulário de login consiste em três elementos: campo de email (ocupa 2/4), campo de senha (1/4) e botão (1/4) da altura da tela. Os três elementos com weight funcionam apenas na orientação 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="Senha"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="Entrar" />
</LinearLayout>
A altura de cada elemento = (parent_height — padding) × (weight / sumWeights). email recebe 2/4 da altura, senha e botão — 1/4 cada. Todos height=0dp, então o tamanho próprio não é considerado — apenas weight funciona.
Um painel com três botões: ícone de voltar (wrap_content), título (preencher o restante) e ícone de menu (wrap_content). weight para o título = 1, botões sem 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>
Os botões de voltar e menu ocupam exatamente o espaço necessário para o ícone. O título (TextView) com width=0dp e weight=1 se estende por todo o espaço restante entre eles. gravity="center_vertical" alinha todos os elementos verticalmente ao centro.
Um cartão de produto: linha horizontal (imagem + bloco de texto vertical). LinearLayout externo HORIZONTAL, interno — VERTICAL para título, descrição e preço.
<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="Nome do produto"
android:textStyle="bold"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Breve descrição do produto em duas linhas"
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>
Imagem à esquerda (80×80dp), à direita — um bloco vertical de três linhas de texto. O LinearLayout interno tem weight=1, então ocupa todo o espaço restante após a imagem. Este é um padrão clássico de cartão de lista encontrado em milhares de aplicativos.
A principal desvantagem do LinearLayout — a necessidade de contêineres aninhados para layouts complexos. Se você precisa organizar elementos em uma grade 2×2 ou fazer uma linha com alinhamento em ambas as bordas, são necessários pelo menos 2–3 níveis de aninhamento. Cada nível de LinearLayout adiciona 2 passagens de onMeasure, o que em dispositivos fracos leva a atrasos perceptíveis durante a renderização.
De acordo com o Android Performance Blog (Google, 2017), cada nível adicional de aninhamento aumenta o tempo de layout em 30–50 μs. Para uma lista de 20 itens com 3 níveis de aninhamento, o atraso pode chegar a 3 ms por elemento — isso é jank perceptível durante a rolagem. ConstraintLayout resolve esse problema através de uma hierarquia plana, substituindo 3–4 LinearLayouts aninhados por um único contêiner de restrições.
Recomendação: use LinearLayout para layouts lineares simples (até 10 elementos, um nível de aninhamento). Para cartões de lista, formulários com alinhamento diferente e telas com estrutura de tabela, escolha ConstraintLayout. Para elementos repetitivos em RecyclerView, use ConstraintLayout no arquivo de layout do item — isso é crítico para o desempenho da rolagem.
Perguntas frequentes
A razão mais comum — o tamanho na direção não está definido como 0dp. Para layout HORIZONTAL você precisa de android:layout_width="0dp", para VERTICAL — android:layout_height="0dp". Se o elemento tiver wrap_content ou match_parent, o weight pode não funcionar ou dar resultados inesperados. A segunda razão — weightSum no pai é menor que a soma dos pesos dos filhos. A terceira — usar match_parent em um elemento filho na direção oposta.
layout_weight é definido em cada elemento filho e determina sua parte do espaço livre. weightSum — um atributo do pai LinearLayout que define a soma máxima de pesos. Por padrão, weightSum = soma de todos os layout_weight dos filhos. Se você definir weightSum = 3, e os filhos tiverem weight=1, cada um ocupará 1/3. Se houver apenas dois filhos com weight=1, o 1/3 restante ficará vazio. weightSum é conveniente para fixar proporções sem recalcular ao adicionar/remover elementos.
Por padrão não há espaços — os elementos são colocados adjacentes. Se aparecerem espaços, verifique: android:divider e android:showDividers no pai, android:layout_margin nos elementos filhos. Além disso, android:weightSum pode afetar — se os elementos usarem weight, pode sobrar espaço vazio entre eles devido a cálculo incorreto. Para espaços zero, defina todas as margens dos filhos como 0dp e remova o divisor.
Para layouts simples unidirecionais (1–5 elementos em uma linha/coluna) LinearLayout é ligeiramente mais rápido — não gasta recursos no cálculo de restrições. Para layouts complexos (mais de 5 elementos, grades, diferentes tipos de alinhamento) ConstraintLayout é mais rápido porque usa uma hierarquia plana em vez de LinearLayouts aninhados. De acordo com testes do Google (Android Performance Blog), ConstraintLayout vence em layouts que exigem 3+ níveis de aninhamento de LinearLayout.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também