Explicamos a essência do RelativeLayout — um ViewGroup no Android SDK para posicionar elementos filhos em relação uns aos outros ou ao contêiner pai. Ao contrário do LinearLayout, que organiza os elementos estritamente em sequência, o RelativeLayout permite colocar qualquer elemento à esquerda, à direita, acima, abaixo ou centralizado em relação a qualquer outro elemento pelo seu ID. Isso torna o RelativeLayout conveniente para layouts sobrepostos e complexos sem aninhamento. As regras básicas estão descritas na documentação do Android Developers.
Principais pontos
RelativeLayout — um ViewGroup introduzido no Android SDK a partir da API Level 1, que posiciona elementos filhos por meio de regras declarativas (layout rules) em relação ao pai ou a outros elementos filhos. Cada regra é definida por um atributo XML como android:layout_above, android:layout_below, android:layout_toLeftOf com o valor do ID do elemento alvo.
Antes do RelativeLayout, os desenvolvedores precisavam usar LinearLayouts aninhados para cada posicionamento não padrão — isso gerava aninhamento profundo e renderização lenta. O RelativeLayout resolveu esse problema oferecendo posicionamento relativo em um único nível hierárquico. No entanto, sua flexibilidade é limitada em comparação com o ConstraintLayout moderno: o RelativeLayout não suporta cadeias, barreiras, guias ou dimensões percentuais.
O RelativeLayout tem duas características principais: uma única passagem onMeasure (ao contrário do LinearLayout com weight, que requer duas passagens) e dependência da ordem de declaração — se o elemento A referencia o elemento B, e B é declarado após A, B deve ter um tamanho conhecido no momento da medição de A. De acordo com o Guia do Desenvolvedor Android (2024), o RelativeLayout realiza a medição em uma única passagem se todas as regras referenciarem elementos já medidos. Caso contrário, uma segunda passagem é necessária, o que reduz o desempenho.
O RelativeLayout é justificado para layouts simples com 3–7 elementos onde é necessário posicionamento relativo (rótulo acima de um botão, ícone à direita do texto, painel na parte inferior da tela). Para novos projetos, o ConstraintLayout é recomendado, mas o RelativeLayout ainda é amplamente usado em código legado e bibliotecas.
O RelativeLayout usa dois tipos de regras: regras relative (posicionamento relativo a outro elemento) e regras align (ancoragem ao pai). Cada elemento filho pode ter um número ilimitado de regras, mas regras conflitantes (ex., alignParentTop e below de outro elemento) são resolvidas em favor do último atributo declarado.
Regras relative:
- android:layout_above="@id/target" — a borda inferior do elemento é ancorada à borda superior do target.
- android:layout_below="@id/target" — a borda superior do elemento é ancorada à borda inferior do target.
- android:layout_toLeftOf="@id/target" — a borda direita é ancorada à borda esquerda do target.
- android:layout_toRightOf="@id/target" — a borda esquerda é ancorada à borda direita do target.
- android:layout_toStartOf="@id/target" — análogo ao toLeftOf para localizações RTL.
- android:layout_toEndOf="@id/target" — análogo ao toRightOf para RTL.
Regras align (ao pai):
- android:layout_alignParentTop="true" — a borda superior do elemento coincide com a borda superior do pai.
- android:layout_alignParentBottom="true" — a borda inferior coincide com a borda inferior do pai.
- android:layout_alignParentLeft="true" — a borda esquerda coincide com a borda esquerda do pai.
- android:layout_alignParentRight="true" — a borda direita coincide com a borda direita do pai.
- android:layout_alignParentStart e android:layout_alignParentEnd — para RTL.
Regras align a outros elementos:
- android:layout_alignTop="@id/target" — o topo do elemento coincide com o topo do target.
- android:layout_alignBottom, android:layout_alignLeft, android:layout_alignRight, android:layout_alignStart, android:layout_alignEnd — análogo.
- android:layout_alignBaseline="@id/target" — alinhamento pela linha de base do texto (útil para strings com diferentes tamanhos de fonte).
A centralização no RelativeLayout é definida por três atributos: android:layout_centerInParent="true" (centro do pai em ambos os eixos), android:layout_centerHorizontal="true" (centro horizontal) e android:layout_centerVertical="true" (centro vertical). A centralização é compatível com outras regras: um elemento pode estar centralizado horizontalmente e ancorado à borda inferior do pai.
A ordem Z (ordem de sobreposição) no RelativeLayout é determinada pela ordem de declaração dos elementos em XML. O primeiro elemento declarado é desenhado primeiro (ficará abaixo), o último — por último (ficará acima). Se precisar alterar a ordem de sobreposição sem alterar o XML, use android:elevation (a partir da API 21) — elementos com elevation maior são desenhados por cima. Para versões abaixo da API 21, a ordem de sobreposição é controlada apenas pela ordem de declaração.
Importante: o RelativeLayout não suporta o atributo android:elevation para o pai — cada elemento controla sua própria elevation. Quando as regras de posicionamento e a elevation entram em conflito (ex., elementos sobrepostos), a elevation tem prioridade para renderização, mas não para posicionamento — um elemento com elevation maior pode sobrepor visualmente outro, mesmo que suas regras de layout o coloquem "atrás".
Avatar centralizado no topo, nome abaixo do avatar, status abaixo do nome, botão de ação na parte inferior da tela. Todos os elementos usam regras relativas para ancoragem sequencial.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/avatar"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:src="@drawable/avatar_placeholder" />
<TextView
android:id="@+id/user_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/avatar"
android:layout_centerHorizontal="true"
android:layout_marginTop="12dp"
android:text="Ivan Ivanov"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="@+id/user_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/user_name"
android:layout_centerHorizontal="true"
android:text="Online"
android:textColor="@color/green" />
<Button
android:id="@+id/edit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="24dp"
android:text="Editar perfil" />
</RelativeLayout>
O avatar está ancorado ao topo via marginTop + centerHorizontal, o nome está abaixo do avatar via layout_below, o status abaixo do nome e o botão ancorado à borda inferior do pai via alignParentBottom. Todos os elementos são independentes entre si — sem cadeias ou aninhamento.
Um ícone com um badge vermelho (círculo com número) no canto superior direito. O badge é posicionado em relação ao ícone através de alinhamento às suas bordas com margens negativas para sobreposição.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@drawable/ic_notification" />
<TextView
android:id="@+id/badge"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignTop="@+id/icon"
android:layout_alignRight="@+id/icon"
android:layout_marginTop="-6dp"
android:layout_marginRight="-6dp"
android:gravity="center"
android:background="@drawable/badge_background"
android:text="3"
android:textColor="@android:color/white"
android:textSize="10sp" />
</RelativeLayout>
O badge está ancorado às bordas superior e direita do ícone. As margens negativas (-6dp) deslocam o badge para fora, criando um efeito de sobreposição da borda do ícone. Este é um padrão popular para notificações, que sem o RelativeLayout exigiria FrameLayout ou desenho personalizado.
Formulário de login: logotipo centralizado no topo, campo de email abaixo, campo de senha abaixo do email, botão "Entrar" abaixo da senha, link "Cadastre-se" ancorado na parte inferior. Todos os elementos são ancorados sequencialmente via layout_below.
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="24dp">
<TextView
android:id="@+id/logo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="48dp"
android:text="MyApp"
android:textSize="32sp"
android:textStyle="bold" />
<EditText
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/logo"
android:layout_marginTop="32dp"
android:hint="Email" />
<EditText
android:id="@+id/password_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/email_input"
android:layout_marginTop="16dp"
android:hint="Senha"
android:inputType="textPassword" />
<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/password_input"
android:layout_marginTop="24dp"
android:text="Entrar" />
<TextView
android:id="@+id/register_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="16dp"
android:text="Não tem conta? Cadastre-se"
android:textColor="@color/primary" />
</RelativeLayout>
A tela usa 5 elementos em um único nível hierárquico. O fluxo de cima para baixo (logo → email → senha → botão) é obtido via layout_below, e o link é empurrado para baixo via alignParentBottom. Para a mesma funcionalidade, o LinearLayout exigiria dois contêineres aninhados (um para o grupo superior, outro para o link com weight).
Comparação de dois ViewGroups para posicionamento relativo: RelativeLayout (clássico, API 1+) e ConstraintLayout (moderno, Jetpack). Critérios: flexibilidade, desempenho, suporte RTL e adaptabilidade.
| Característica | RelativeLayout | ConstraintLayout |
|---|---|---|
| Dimensões percentuais | Não (apenas fixas e match_parent) | Sim (width_percent, height_percent, guideline_percent) |
| Suporte RTL | Via start/end (API 17+) | Integrado |
| Chain / cadeias | Não | Sim (spread, spread_inside, packed) |
| Barrier / Group / Flow | Não | Sim (assistentes virtuais) |
| animações MotionLayout | Não | Sim |
| Passagens onMeasure | 1 (sem ciclos de dependência) | 2 (sempre, mas otimizadas) |
| Centralização | centerInParent, centerHorizontal, centerVertical | Via bias (0.0–1.0) com restrições opostas |
| Quando usar | Código legado, layouts simples com 3–7 elementos | Novos projetos, telas complexas, layouts adaptativos |
O RelativeLayout é inferior ao ConstraintLayout em quase todos os aspectos, exceto um: ele está integrado ao Android SDK desde a API 1 e não requer dependências adicionais. Para projetos que ainda usam minSdk abaixo da API 14 (Android 4.0), o RelativeLayout é a única opção padrão para posicionamento relativo. Em todos os outros casos, o Google recomenda o ConstraintLayout.
Perguntas frequentes
A razão mais provável é a falta de regras de posicionamento suficientes. Cada elemento no RelativeLayout deve ter pelo menos uma regra horizontal (alignParentLeft, toRightOf, centerHorizontal) e uma regra vertical (alignParentTop, below, centerVertical). Se não houver regras, o elemento fica na posição (0,0) e pode ficar oculto sob outros elementos ou fora da tela. A segunda razão é uma dependência circular (elemento A vinculado a B, B vinculado a A), que leva a um comportamento imprevisível.
Use o atributo android:layout_centerInParent="true". Ele centraliza o elemento em ambos os eixos simultaneamente. Se precisar apenas horizontalmente — android:layout_centerHorizontal="true", apenas verticalmente — android:layout_centerVertical="true". A centralização funciona em combinação com margens — o elemento será deslocado em relação ao centro pelo deslocamento especificado.
Sim, mas não é recomendado. O RelativeLayout realiza duas passagens onMeasure na presença de dependências circulares, o que é 15–30% mais lento que o ConstraintLayout em listas do RecyclerView. Para layouts de itens do RecyclerView, use ConstraintLayout — ele fornece uma hierarquia plana com tempo mínimo de medição. Se o RelativeLayout já estiver sendo usado em um projeto legado, certifique-se de que os elementos não criem dependências circulares e meça o FPS de rolagem através do Profile GPU Rendering.
android:layout_margin define margens em todos os lados simultaneamente. android:layout_marginTop — apenas no topo. O atributo mais específico tem prioridade: se ambos layout_margin (16dp) e layout_marginTop (8dp) forem definidos, a margem superior será 8dp. No RelativeLayout, a margem funciona em relação à restrição, não em relação ao elemento adjacente: layout_marginTop com layout_below="@id/target" é a margem da borda superior do elemento até a borda inferior do target.
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