FrameLayout: Conceitos-chave, posicionamento simples no Android

Autor: IT Sectr Publicado: 2026-02-24 Tempo de leitura: 8 min

Aprenda os conceitos-chave do FrameLayout — a ViewGroup mais simples no Android SDK, projetada para hospedar um único elemento filho (normalmente) ou sobrepor vários elementos uns sobre os outros. O FrameLayout é conveniente para contêineres placeholder, fragmentos, indicadores de carregamento e elementos de primeiro plano. Ele não gerencia o posicionamento dos filhos — cada elemento subsequente é desenhado sobre o anterior, e sua posição é determinada por layout_gravity (left, top, right, bottom, center). Os cenários básicos estão descritos na Referência da API FrameLayout.

Principais conclusões

  • Sobreposição de camadas — o FrameLayout coloca os elementos sequencialmente uns sobre os outros; o último declarado em XML desenha-se mais alto.
  • Primeiro plano — o atributo android:foreground permite sobrepor um drawable sobre todos os elementos filhos, útil para efeitos e mascaramento.
  • measureAllChildren — por padrão, o FrameLayout mede todos os filhos, mesmo os invisíveis (GONE). Desativá-lo acelera o desenho em 20–60%.
  • layout_gravity — a única forma de posicionar um elemento filho dentro do FrameLayout: top, bottom, left, right, center.
  • Uso com Fragment — o FrameLayout é o contêiner padrão para FragmentTransaction.replace(), substituindo conteúdo sem recriar a atividade.

O que é FrameLayout?

FrameLayout é a ViewGroup mais simples do Android SDK, projetada para bloquear uma área da tela e exibir uma única view filha (ou sobrepor várias). Ao contrário do LinearLayout (disposição sequencial) e RelativeLayout (posicionamento relativo), o FrameLayout não altera as posições dos filhos — cada novo filho é colocado no canto superior esquerdo (0,0) por padrão e desenhado sobre o anterior.

O FrameLayout foi introduzido na API Level 1 e continua sendo o contêiner Android mais leve: ele não substitui onMeasure com lógica complexa e realiza um número mínimo de operações de layout. De acordo com o Android Performance Blog, o FrameLayout executa onLayout em uma única passagem e praticamente não adiciona sobrecarga em comparação com colocar uma View diretamente. Isso o torna uma escolha ideal para contêineres onde a velocidade importa: layouts de itens RecyclerView (combinados com ConstraintLayout para posicionamento), contêineres de Fragment, camadas de sobreposição.

O tamanho do FrameLayout por padrão é determinado pelo maior elemento filho (se match_parent não for definido). Se nenhum filho for especificado, o FrameLayout se contrai para (0,0). O atributo android:measureAllChildren (seção abaixo) altera esse comportamento.

FrameLayout na hierarquia ViewGroup do Android

FrameLayout herda de ViewGroup e é o pai direto de muitos contêineres especializados: FragmentContainerView (fragmentos), CardView (cartões com sombra), ScrollView (filho único), NestedScrollView. Ao criar uma Activity com navegação por Fragment, o modelo padrão do Android Studio usa FrameLayout (ou FragmentContainerView) como contêiner raiz para fragmentos.

Primeiro plano e measureAllChildren

android:foreground — um atributo FrameLayout que especifica um drawable desenhado sobre todos os elementos filhos. Ao contrário de background (sob os filhos), o foreground é exibido acima do conteúdo e pode ser transparente. É usado para: efeitos de sobreposição ao pressionar (ripple via ?attr/selectableItemBackground), mascaramento de imagens, exibição de indicadores de status (marca de seleção sobre uma imagem).

Foreground suporta recursos drawable padrão: ColorDrawable, ShapeDrawable, RippleDrawable, LayerDrawable. Desde a API 23+, android:foregroundGravity está disponível para posicionamento do foreground (fill, center, top, bottom). No modo fill, foreground se estende por todo o FrameLayout; no modo center, desenha-se no centro.

android:measureAllChildren — um atributo booleano (true por padrão) que determina se todos os elementos filhos devem ser medidos ao calcular o tamanho do FrameLayout. Se true (padrão), o FrameLayout considera os tamanhos de todos os filhos, incluindo GONE (com tamanho 0). Se false, o FrameLayout mede apenas filhos VISIBLE e INVISIBLE — elementos GONE são excluídos do cálculo. De acordo com o Google I/O 2019, desativar measureAllChildren para contêineres com muitos elementos GONE (por exemplo, listas com alternância de visibilidade) acelera o desenho inicial em 20–60%.

layout_gravity: Posicionamento dentro do FrameLayout

android:layout_gravity — um atributo de um elemento filho do FrameLayout (e outros ViewGroups) que define sua posição dentro do contêiner. No FrameLayout, layout_gravity é a única maneira de controlar a posição de um elemento filho, já que o FrameLayout não fornece suas próprias regras de posicionamento (como RelativeLayout) ou direção (como LinearLayout).

Valores possíveis: top, bottom, left, right, center, center_horizontal, center_vertical, fill, fill_horizontal, fill_vertical, clip_horizontal, clip_vertical. Combinados via |: android:layout_gravity="bottom|center_horizontal" — o elemento é fixado na borda inferior e centralizado horizontalmente. Para elementos menores que o FrameLayout, layout_gravity determina sua posição no espaço livre.

Se layout_gravity não for definido, o elemento é colocado no canto superior esquerdo (top|left) por padrão. Para um FrameLayout contendo vários filhos, cada um pode ter seu próprio layout_gravity — um elemento pode estar no canto superior esquerdo, outro no canto inferior direito, um terceiro centralizado. Isso permite criar sobreposições simples (por exemplo, um ícone de fechar sobre uma imagem).

Diferença: gravity vs layout_gravity

android:gravity (atributo pai) alinha o conteúdo dentro do FrameLayout — por exemplo, texto dentro de um TextView. android:layout_gravity (atributo filho) alinha o próprio elemento dentro do FrameLayout. No contexto do FrameLayout, gravity define como os filhos são posicionados por padrão (semelhante a layout_gravity para todos os filhos de uma vez), mas o layout_gravity de cada elemento específico substitui o valor do pai.

Exemplos: XML e casos de uso

Exemplo 1: Sobreposição básica — Rótulo em imagem

Uma imagem com um rótulo de texto no canto inferior direito. FrameLayout contém um ImageView preenchendo a tela e um TextView com layout_gravity="bottom|end" para posicionamento sobre a imagem.

xml
<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="200dp">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:src="@drawable/product_photo"
        android:scaleType="centerCrop" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="8dp"
        android:background="@drawable/badge_background"
        android:elevation="2dp"
        android:paddingHorizontal="8dp"
        android:paddingVertical="4dp"
        android:text="-30%"
        android:textColor="@android:color/white"
        android:textSize="14sp"
        android:textStyle="bold" />

</FrameLayout>

O ImageView preenche todo o FrameLayout (altura de 200dp). O TextView com layout_gravity="bottom|end" é colocado no canto inferior direito sobre a imagem. elevation=2dp adiciona uma sombra sob o rótulo, separando-o visualmente da imagem. Este exemplo mínimo exigiria um contêiner aninhado ou código personalizado no LinearLayout.

Exemplo 2: Indicador de carregamento (barra de progresso sobre o conteúdo)

Uma tela com conteúdo e uma barra de progresso centralizada que aparece durante o carregamento. FrameLayout contém dois elementos: conteúdo e um ProgressBar com visibility="gone" (alternado no código).

xml
<FrameLayout
    android:id="@+id/content_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/content_text"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Conteúdo carregado"
        android:textSize="18sp" />

    <ProgressBar
        android:id="@+id/loading_spinner"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:layout_gravity="center"
        android:visibility="gone" />

</FrameLayout>

O ProgressBar está oculto por padrão (gone). Quando o carregamento começa, findViewById(R.id.loading_spinner).visibility = View.VISIBLE é chamado — o spinner aparece centralizado sobre o conteúdo. Após o carregamento — .visibility = View.GONE. FrameLayout fornece sobreposição sem deslocar a posição do conteúdo — o texto não se move quando o spinner aparece, pois o ProgressBar desenha por cima.

Exemplo 3: Contêiner de Fragment

FrameLayout como contêiner padrão para FragmentTransaction. A atividade substitui fragmentos dentro deste contêiner conforme a navegação.

xml
<FrameLayout
    android:id="@+id/fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
kotlin
import androidx.fragment.app.FragmentTransaction

val fragmentContainer = R.id.fragment_container

fun navigateTo(fragment: Fragment) {
    supportFragmentManager
        .beginTransaction()
        .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
        .replace(fragmentContainer, fragment)
        .addToBackStack(null)
        .commit()
}

FrameLayout como contêiner de fragmentos é a maneira mais leve de suportar a navegação por Fragmentos. FragmentContainerView (subclasse de FrameLayout) é recomendado com Navigation Component 2.4+, mas um FrameLayout simples permanece válido para FragmentTransactions manuais. A principal vantagem é que FragmentTransaction.replace() substitui completamente o conteúdo sem afetar a Activity.

Quando usar FrameLayout

FrameLayout é ideal para quatro cenários: contêiner de fragmentos (FragmentContainerView ou FrameLayout), sobreposição de carregamento (ProgressBar sobre conteúdo), rótulos em cartões (rótulo em imagem), contêiner placeholder para ViewStub (carregamento lento).

Não é adequado para: posicionamento complexo de vários elementos (use ConstraintLayout), listas sequenciais (LinearLayout ou RecyclerView), layouts dinâmicos com alteração de ordem dos elementos.

FrameLayout como elemento raiz da tela — prática ruim se a tela contiver mais de 2–3 elementos. Para um contêiner raiz, use ConstraintLayout — ele dá mais controle sobre o posicionamento sem perda de desempenho. Use FrameLayout apenas para blocos filhos onde seja necessária sobreposição ou placeholder.

Perguntas frequentes

Qual a diferença entre FrameLayout e ConstraintLayout?

FrameLayout — um contêiner minimalista sem sistema de posicionamento (apenas layout_gravity), projetado para sobreposição de elementos. ConstraintLayout — um sistema de layout completo com constraints, cadeias, barreiras, dimensões percentuais e suporte a MotionLayout. FrameLayout é mais rápido para casos simples (1 filho ou sobreposição); ConstraintLayout é necessário para layouts complexos. Escolha: FrameLayout para sobreposição de carregamento e contêiner de fragmentos; ConstraintLayout para todo o resto.

Como fazer FrameLayout ocupar apenas o espaço do maior filho?

Defina o tamanho do FrameLayout como wrap_content no eixo desejado (android:layout_width="wrap_content" e/ou android:layout_height="wrap_content"). O FrameLayout então se ajustará ao tamanho do maior elemento filho. Se todos os filhos forem menores que o FrameLayout, o espaço excedente permanece vazio. Para controle preciso, use match_parent com padding fixo.

Por que os elementos no FrameLayout se sobrepõem uns aos outros?

Este é o comportamento pretendido do FrameLayout — ele não distribui os filhos no espaço, mas os desenha sequencialmente uns sobre os outros. Se você quiser que os elementos não se sobreponham, use outro contêiner (LinearLayout, ConstraintLayout). Para sobreposição parcial com controle da ordem de desenho, use layout_gravity para deslocamento e elevation para ordem Z.

Qual é mais rápido: FrameLayout ou ConstraintLayout?

FrameLayout é mais rápido para os casos mais simples — um elemento filho, sem posicionamento complexo. FrameLayout executa onMeasure em tempo mínimo sem calcular constraints. No entanto, a diferença é perceptível apenas em centenas de repetições (RecyclerView com dezenas de milhares de itens). Para uma tela típica (1–3 FrameLayouts), a diferença é de microssegundos e não afeta a UX. ConstraintLayout é a escolha universal para 95% das tarefas.

Resumo

  • FrameLayout — a ViewGroup Android mais simples para sobreposição de elementos e contêineres placeholder com sobrecarga mínima.
  • Sobreposição de camadas — cada novo filho desenha-se sobre o anterior; o último declarado em XML é o mais alto.
  • Primeiro plano — um drawable sobre todos os filhos para efeitos de sobreposição, mascaramento e animações ripple.
  • measureAllChildren — desativar (false) exclui elementos GONE do cálculo de tamanho, acelerando o desenho em 20–60%.
  • layout_gravity — o único mecanismo de posicionamento: top, bottom, left, right, center e suas combinações.
  • Contêiner de Fragment — o caso de uso mais comum: FrameLayout (ou FragmentContainerView) para FragmentTransaction.replace().
  • Desempenho — o contêiner mais rápido para 1 filho; para layouts complexos, fica atrás do ConstraintLayout.

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.

Discutir o projeto

Leia também