Una vez que orientes tu app al SDK 35 o versiones posteriores en un dispositivo con Android 15 o versiones posteriores, se mostrará de borde a borde. La ventana abarca todo el ancho y el alto de la pantalla. Para ello, se dibuja detrás de las barras del sistema. Las barras del sistema incluyen la barra de estado, de subtítulos y de navegación.
Muchas apps tienen una barra superior. La barra superior de la app debe extenderse hasta el borde superior de la pantalla y aparecer detrás de la barra de estado. De manera opcional, la barra superior de la app puede reducirse a la altura de la barra de estado cuando se desplaza el contenido.
Muchas apps también tienen una barra inferior de la aplicación o de navegación. Estas barras también deben extenderse hasta el borde inferior de la pantalla y mostrarse detrás de la barra de navegación. De lo contrario, las apps deberían mostrar contenido desplazable detrás de la barra de navegación.
Cuando implementes un diseño de borde a borde en tu app, ten en cuenta lo siguiente:
- Cómo habilitar una pantalla de borde a borde
- Controla las superposiciones visuales.
- Considera mostrar láminas detrás de las barras del sistema.
Cómo habilitar la pantalla de borde a borde
Si tu app se orienta al SDK 35 o versiones posteriores, la opción de borde a borde se habilita automáticamente para dispositivos con Android 15 o versiones posteriores.
Para habilitar la función de borde a borde en versiones anteriores de Android, haz lo siguiente:
Agrega una dependencia a la biblioteca
androidx.activity
en el archivobuild.gradle
de tu app o módulo:Kotlin
dependencies { val activity_version =
activity_version
// Java language implementation implementation("androidx.activity:activity:$activity_version") // Kotlin implementation("androidx.activity:activity-ktx:$activity_version") }Groovy
dependencies { def activity_version =
activity_version
// Java language implementation implementation 'androidx.activity:activity:$activity_version' // Kotlin implementation 'androidx.activity:activity-ktx:$activity_version' }Importa la función de extensión
enableEdgeToEdge
a tu app:
Llama a enableEdgeToEdge
en onCreate
de tu Activity
para habilitar manualmente el borde a borde. Se debe llamar 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); ... }
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 tiene 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.
La función enableEdgeToEdge()
declara automáticamente que la app debe colocarse de borde a borde y ajusta los colores de las barras del sistema.
Para habilitar la pantalla de borde a borde en tu app sin usar la función enableEdgeToEdge()
, consulta Cómo configurar manualmente la pantalla de borde a borde.
Cómo controlar las superposiciones con inserciones
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, reacciona 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 arriba del contenido, pero también puede informar a tu app sobre 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 las barras del sistema no deben oscurecer visualmente.
Inserciones de corte de pantalla: Para áreas en las que puede haber un corte de pantalla debido a la forma del dispositivo
Inserciones de gestos del sistema: Para las áreas de navegación por gestos que usa el sistema y que tienen prioridad sobre la app.
Inserciones de barras del sistema
Las inserciones de la barra del sistema son el tipo de inserciones más utilizado. Representan el área donde se muestra la IU del sistema en el eje Z sobre tu app. Se recomienda su uso para mover o rellenar vistas en tu app que se pueden presionar y que no deben estar visualmente ocultas por las barras del sistema.
Por ejemplo, el botón de acción flotante (BAF) de la figura 3 está parcialmente oscurecido por la barra de navegación:
Para evitar este tipo de superposición visual en el modo de gesto o de botones, puedes aumentar los márgenes de la vista usando 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 que se muestra en la figura 3, no se producirá una superposición visual en el modo de botón, como se muestra en la figura 4:
Lo mismo se aplica al modo de navegación por gestos, como se muestra en la figura 5:
Inserciones de corte de pantalla
Algunos dispositivos tienen cortes de pantalla. Por lo general, el corte se encuentra en la parte superior de la pantalla y se incluye en la barra de estado. Cuando la pantalla del dispositivo está en modo horizontal, el corte puede estar en el borde vertical. Según el contenido que muestre tu app en la pantalla, debes implementar el padding para evitar los cortes de pantalla, ya que, de forma predeterminada, las apps se dibujarán en el corte de pantalla.
Por ejemplo, muchas pantallas de la app muestran una lista de elementos. No ocultes los elementos de lista con el corte de pantalla o las barras del sistema.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { WindowInsetsCompat bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
Para determinar el valor de WindowInsetsCompat
, toma el or lógico de las barras del sistema y los tipos de corte de pantalla.
Establece clipToPadding
en RecyclerView
para que el padding se desplace con los elementos de la lista. Esto permite que los elementos se ubiquen detrás de las barras del sistema cuando el usuario se desplaza, como se muestra en el siguiente ejemplo.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
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:
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 las vistas deslizables hacia afuera de los bordes. Entre los casos de uso comunes, se incluyen las hojas inferiores, el deslizamiento en juegos y los 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 la izquierda y la derecha para los gestos de retroceso:
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; });
Componentes de Material
Muchos componentes de material de Android basados en vistas (com.google.android.material){:.external} controlan automáticamente las inserciones, como BottomAppBar
, BottomNavigationView
, NavigationRailView
y NavigationView
.
Sin embargo, AppBarLayout
no controla automáticamente las inserciones. Agrega android:fitsSystemWindows="true"
para controlar las inserciones superiores o usa setOnApplyWindowInsetsListener
.
Obtén información para controlar las inserciones con Componentes de Material en Compose.
Modo envolvente
Algunos contenidos se disfrutan mejor en pantalla completa, lo que le brinda al usuario una experiencia más envolvente. Puedes ocultar las barras del sistema y el modo envolvente con las bibliotecas WindowInsetsController
y 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());
Consulta Cómo ocultar las barras del sistema para el modo envolvente para 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:
- WindowInsets: objetos de escucha para los diseños
- Navegación por gestos: Inserciones
- ¿Cómo funcionan las inserciones en Android?