Mostrar conteúdo de ponta a ponta no app

Testar o Compose
O Jetpack Compose é o kit de ferramentas de interface recomendado para Android. Aprenda a trabalhar com ponta a ponta no Compose.

Você pode fazer o app aparecer de ponta a ponta, usando toda a largura e altura da tela, desenhando atrás das barras do sistema. As barras de sistema são a barra de status e a barra de navegação.

Para implementar um layout de ponta a ponta, seu app precisa fazer o seguinte:

  • Desenhe por trás da barra de navegação para oferecer uma experiência do usuário mais interessante e moderna.
  • Desenhe atrás da barra de status se fizer sentido para seu conteúdo e layout, como no caso de imagens de largura total. Para fazer isso, use APIs como AppBarLayout, que define uma barra de apps fixada na parte de cima da tela.
Figura 1. Barras de sistema em um layout de ponta a ponta.

Para implementar um layout de ponta a ponta no app, siga estas etapas:

  1. Ative a exibição de ponta a ponta.
  2. Gerencie as sobreposições visuais.
Uma imagem que mostra um app com imagens atrás da barra de status
Figura 2. Exemplo de um app com imagens por trás da barra de status.

Ative a exibição de ponta a ponta.

Você pode ativar a exibição de ponta a ponta no app chamando enableEdgeToEdge em onCreate do Activity. Ele precisa ser chamado antes de setContentView.

Kotlin

  override fun onCreate(savedInstanceState: Bundle?) {
    enableEdgeToEdge()
    super.onCreate(savedInstanceState)
    ...
  }

Java

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    EdgeToEdge.enable(this);
    super.onCreate(savedInstanceState);
    ...
  }

Por padrão, enableEdgeToEdge torna as barras do sistema transparentes, exceto no modo de navegação com três botões, em que a barra de status tem um scrim translúcido. As cores dos ícones do sistema e do scrim são ajustadas com base no tema claro ou escuro do sistema.

O método enableEdgeToEdge declara automaticamente que o app precisa ser disposto de ponta a ponta e ajusta as cores das barras do sistema. Consulte Configurar manualmente a exibição de ponta a ponta se isso for necessário por algum motivo.

Processar sobreposições usando encartes

Depois de ativar a tela de ponta a ponta, algumas das visualizações do app podem ser mostradas atrás das barras de sistema, como mostrado na Figura 3.

Você pode resolver as sobreposições reagindo aos encartes, que especificam quais partes da tela se cruzam com a IU do sistema, como a barra de navegação ou a barra de status. A interseção pode significar a exibição acima do conteúdo, mas também pode informar ao app sobre gestos do sistema.

Os tipos de encarte que se aplicam à exibição do app de ponta a ponta são:

  • Encartes das barras de sistema:melhor para visualizações totáveis e que não podem ser visualmente obscurecidas pelas barras de sistema.

  • Encartes de gestos do sistema:para áreas de navegação por gestos usadas pelo sistema e que têm prioridade sobre o app.

Encartes de barras do sistema

Os encartes da barra do sistema são o tipo mais usado. Eles representam a área em que a interface do sistema é mostrada no eixo Z acima do app. Eles são mais usados para mover ou preencher visualizações no app que podem ser tocadas e que não podem ser visualmente obscurecidas pelas barras do sistema.

Por exemplo, o botão de ação flutuante (FAB, na sigla em inglês) na Figura 3 é parcialmente oculto pela barra de navegação:

Uma imagem mostrando a implementação de ponta a ponta implementada, mas a barra de navegação está cobrindo o FAB
Figura 3. Barra de navegação sobreposta a um FAB em um layout de ponta a ponta.

Para evitar esse tipo de sobreposição visual no modo de gesto ou de botão, você pode aumentar as margens da visualização usando getInsets(int) com WindowInsetsCompat.Type.systemBars().

O exemplo de código a seguir mostra como implementar encartes de barra do sistema:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets ->
  val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
  // Apply the insets as a margin to the view. This solution sets
  // only the bottom, left, and right dimensions, but you can apply whichever
  // insets are appropriate to your layout. You can also update the view padding
  // if that's more appropriate.
  v.updateLayoutParams<MarginLayoutParams> {
      leftMargin = insets.left,
      bottomMargin = insets.bottom,
      rightMargin = insets.right,
  }

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
  WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> {
  Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
  // Apply the insets as a margin to the view. This solution sets only the
  // bottom, left, and right dimensions, but you can apply whichever insets are
  // appropriate to your layout. You can also update the view padding if that's
  // more appropriate.
  MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams();
  mlp.leftMargin = insets.left;
  mlp.bottomMargin = insets.bottom;
  mlp.rightMargin = insets.right;
  v.setLayoutParams(mlp);

  // Return CONSUMED if you don't want want the window insets to keep passing
  // down to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

Se você aplicar essa solução ao exemplo mostrado na Figura 3, não haverá sobreposição visual no modo de botão, como mostrado na Figura 4:

Imagem mostrando uma barra de navegação translúcida que não cobre o FAB
Figura 4. Resolução de sobreposição visual no modo de botão.

O mesmo se aplica ao modo de navegação por gestos, como mostrado na Figura 5:

Uma imagem mostrando a navegação por gestos de ponta a ponta
Figura 5. Resolução de sobreposição visual no modo de navegação por gestos.

Encartes de gestos do sistema

Os encartes de gestos do sistema representam as áreas da janela em que os gestos do sistema têm prioridade sobre o app. Essas áreas são mostradas em laranja na Figura 6:

Imagem mostrando encartes de gestos do sistema
Figura 6. Encartes de gestos do sistema.

Assim como os encartes da barra do sistema, você pode evitar a sobreposição dos encartes do gesto do sistema usando getInsets(int) com WindowInsetsCompat.Type.systemGestures().

Use esses encartes para mover ou preencher visualizações deslizantes para longe das bordas. Casos de uso comuns incluem páginas inferiores, deslizar em jogos e carrosséis implementados usando ViewPager2.

No Android 10 ou versões mais recentes, os encartes de gestos do sistema contêm um encarte de baixo para o gesto de início e um encarte à esquerda e à direita para os gestos "Voltar":

Imagem mostrando medições de encarte de gestos do sistema
Figura 7. Medições de encarte de gestos do sistema.

O exemplo de código abaixo mostra como implementar encartes de gestos do sistema:

Kotlin

ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
    val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures())
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.updatePadding(insets.left, insets.top, insets.right, insets.bottom)

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    WindowInsetsCompat.CONSUMED
}

Java

ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> {
    Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures());
    // Apply the insets as padding to the view. Here, set all the dimensions
    // as appropriate to your layout. You can also update the view's margin if
    // more appropriate.
    view.setPadding(insets.left, insets.top, insets.right, insets.bottom);

    // Return CONSUMED if you don't want the window insets to keep passing down
    // to descendant views.
    return WindowInsetsCompat.CONSUMED;
});

Modo imersivo

Alguns conteúdos são melhores em tela cheia, oferecendo ao usuário uma experiência mais imersiva. Você pode ocultar as barras de sistema para o modo imersivo usando as bibliotecas WindowInsetsController e WindowInsetsControllerCompat:

Kotlin

val windowInsetsController =
      WindowCompat.getInsetsController(window, window.decorView)

// Hide the system bars.
windowInsetsController.hide(Type.systemBars())

// Show the system bars.
windowInsetsController.show(Type.systemBars())

Java

Window window = getWindow();
WindowInsetsControllerCompat windowInsetsController =
      WindowCompat.getInsetsController(window, window.getDecorView());
if (windowInsetsController == null) {
    return;
  }
// Hide the system bars.
windowInsetsController.hide(WindowInsetsCompat.Type.systemBars());

// Show the system bars.
windowInsetsController.show(WindowInsetsCompat.Type.systemBars());

Consulte Ocultar barras de sistema para o modo imersivo para mais informações sobre como implementar esse recurso.

Outros recursos

Consulte as referências abaixo para saber mais sobre o WindowInsets, a navegação por gestos e como os encartes funcionam: