Cómo mostrar el contenido de borde a borde en la app

Prueba el estilo de Compose
Jetpack Compose es el kit de herramientas de IU recomendado para Android. Obtén información para trabajar con borde a borde en Compose.

Para que la app muestre de borde a borde, usando todo el ancho y la altura de la pantalla, dibuja detrás de las barras del sistema. Las barras del sistema son la barra de estado y la barra de navegación.

Para implementar un diseño de borde a borde, tu app debe hacer lo siguiente:

  • Dibuja detrás de la barra de navegación para lograr una experiencia del usuario más moderna y atractiva.
  • Dibuja detrás de la barra de estado si es relevante para tu contenido y diseño, como en el caso de las imágenes de ancho completo. Para ello, usa APIs como AppBarLayout, que define una barra de la app fijada en la parte superior de la pantalla.
Figura 1: Barras del sistema en un diseño de borde a borde

Para implementar un diseño de borde a borde en tu app, sigue estos pasos:

  1. Habilita la pantalla de borde a borde.
  2. Controla las superposiciones visuales.
Una imagen que muestra una app con imágenes detrás de la barra de estado
Figura 2: Ejemplo de una app con imágenes detrás de la barra de estado

Habilita la pantalla de borde a borde.

Para habilitar la pantalla de borde a borde en tu app, llama a enableEdgeToEdge en onCreate de tu Activity. Se debe llamar antes del 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);
    ...
  }

De forma predeterminada, enableEdgeToEdge hace que las barras del sistema sean transparentes, excepto en el modo de navegación de 3 botones, en el que la barra de estado obtiene una lámina translúcida. Los colores de los íconos del sistema y de la lámina se ajustan según el tema oscuro o claro del sistema.

El método enableEdgeToEdge declara automáticamente que la app debe distribuirse de borde a borde y ajusta los colores de las barras del sistema. Consulta "Cómo configurar manualmente la pantalla de borde a borde" si es necesario por algún motivo.

Controla las superposiciones con las inserciones

Después de habilitar la pantalla de borde a borde, es posible que algunas de las vistas de tu app se dibujen detrás de las barras del sistema, como se muestra en la Figura 3.

Para abordar las superposiciones, puedes reaccionar a las inserciones, que especifican qué partes de la pantalla se cruzan con la IU del sistema, como la barra de navegación o la barra de estado. La intersección puede significar mostrar imágenes sobre el contenido, pero también puede informar a tu app sobre los gestos del sistema.

Los tipos de inserciones que se aplican para mostrar tu app de borde a borde son los siguientes:

  • Inserciones de barras del sistema: La mejor opción para las vistas que se pueden presionar y que no deben estar ocultas visualmente por las barras del sistema.

  • Inserciones de gestos del sistema: Para las áreas de navegación por gestos que usa el sistema y que tienen prioridad sobre tu app.

Inserciones de las barras del sistema

Las inserciones de la barra del sistema son el tipo de inserción más usado. Representan el área en la que se muestra la IU del sistema en el eje Z, por encima de tu app. Se usan mejor para mover o rellenar vistas de tu app que se pueden presionar y que las barras del sistema no deben ocultar visualmente.

Por ejemplo, el botón de acción flotante (BAF) de la figura 3 está parcialmente oscurecido por la barra de navegación:

Imagen que muestra la implementación de borde a borde, pero la barra de navegación cubre el BAF
Figura 3: Barra de navegación superpuesta a un BAF en un diseño de borde a borde

Para evitar este tipo de superposición visual en el modo de gestos o de botones, puedes aumentar los márgenes de la vista mediante getInsets(int) con WindowInsetsCompat.Type.systemBars().

En el siguiente ejemplo de código, se muestra cómo implementar las inserciones de barra del 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;
});

Si aplicas esta solución al ejemplo de la figura 3, no se producirá una superposición visual en el modo de botón, como se muestra en la figura 4.

Una imagen que muestra una barra de navegación translúcida que no cubre el BAF
Figura 4: Resuelve la superposición visual en el modo de botones.

Lo mismo se aplica al modo de navegación por gestos, como se muestra en la figura 5:

Imagen que muestra de borde a borde con la navegación por gestos
Figura 5: Resolución de la superposición visual en el modo de navegación por gestos

Inserciones de gestos del sistema

Las inserciones de gestos del sistema representan las áreas de la ventana en las que los gestos del sistema tienen prioridad sobre tu app. En la figura 6, estas áreas se muestran en naranja:

Una imagen que muestra las inserciones de gestos del sistema
Figura 6: Inserciones de gestos del sistema

Al igual que las inserciones de la barra del sistema, puedes evitar la superposición de las inserciones de gestos del sistema usando getInsets(int) con WindowInsetsCompat.Type.systemGestures().

Usa estas inserciones para mover o rellenar vistas deslizables para alejarlas de los bordes. Los casos de uso comunes incluyen hojas inferiores, deslizamiento en juegos y carruseles implementados con ViewPager2.

En Android 10 o versiones posteriores, las inserciones de gestos del sistema contienen una inserción inferior para el gesto de inicio y una inserción de izquierda y derecha para los gestos de retroceso:

Una imagen que muestra las mediciones de las inserciones de gestos del sistema
Figura 7: Mediciones de inserción de gestos del sistema.

En el siguiente ejemplo de código, se muestra cómo implementar las inserciones de gestos del 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 envolvente

Parte del contenido se experimenta mejor en pantalla completa, lo que le da al usuario una experiencia más envolvente. Puedes ocultar las barras del sistema para el modo envolvente mediante las bibliotecas WindowInsetsController y WindowInsetsControllerCompat:

Kotlin

val windowInsetsController =
      WindowCompat.getWindowInsetsController(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.getWindowInsetsController(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());

Consulta Cómo ocultar las barras del sistema para el modo envolvente si quieres obtener más información sobre la implementación de esta función.

Recursos adicionales

Consulta las siguientes referencias para obtener más información sobre WindowInsets, la navegación por gestos y el funcionamiento de las inserciones: