Una vez que tu actividad haya tomado el control del procesamiento de todas las inserciones, puedes usar las APIs de Compose para verificar que el contenido no esté oculto y que los elementos interactivos no se superpongan con la IU del sistema. Estas APIs también sincronizan el diseño de tu app con los cambios de inserción.
Cómo controlar las inserciones con modificadores de padding o tamaño
Por ejemplo, este es el método más básico para aplicar las inserciones al contenido de toda tu app:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Este fragmento aplica las inserciones de ventana safeDrawing como relleno alrededor de todo el contenido de la app. Si bien esto garantiza que los elementos interactivos no se superpongan con la IU del sistema, también significa que ninguna parte de la app se dibujará detrás de la IU del sistema para lograr un efecto de borde a borde. Para aprovechar al máximo toda la ventana, debes ajustar con precisión dónde se aplican las inserciones en cada pantalla o componente.
Todos estos tipos de inserciones se animan automáticamente con las animaciones del IME que se portaron a la API 21. Por extensión, todos tus diseños que usan estas inserciones también se animan automáticamente a medida que cambian los valores de inserción.
Existen tres formas de controlar las inserciones para ajustar tus diseños de elementos componibles:
Modificadores de padding
Modifier.windowInsetsPadding(windowInsets: WindowInsets) aplica las inserciones de ventana proporcionadas como relleno, y funciona igual que Modifier.padding.
Por ejemplo, Modifier.windowInsetsPadding(WindowInsets.safeDrawing) aplica las inserciones de dibujo seguras como padding en los 4 lados.
También hay varios métodos de utilidad integrados para los tipos de inserción más comunes.
Modifier.safeDrawingPadding() es uno de esos métodos, equivalente a Modifier.windowInsetsPadding(WindowInsets.safeDrawing). Existen modificadores análogos para los otros tipos de inserción.
Modificadores de tamaño de inserción
Los siguientes modificadores aplican una cantidad de inserciones de ventana estableciendo el tamaño del componente para que sea el tamaño de las inserciones:
Aplica el lado inicial de windowInsets como el ancho (como |
|
Aplica el lado final de windowInsets como el ancho (como |
|
Aplica el lado superior de WindowInsets como la altura (como |
|
|
Aplica el lado inferior de windowInsets como la altura (como |
Estos modificadores son especialmente útiles para dimensionar un Spacer que ocupa el espacio de las inserciones:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consumo de inserciones
Los modificadores de padding de inserción (windowInsetsPadding y asistentes como safeDrawingPadding) consumen automáticamente la porción de las inserciones que se aplican como padding. A medida que profundizas en el árbol de composición, los modificadores de padding de inserción anidados y los modificadores de tamaño de inserción saben que los modificadores de padding de inserción externos ya consumieron una parte de las inserciones y evitan usar la misma parte de las inserciones más de una vez, lo que generaría demasiado espacio adicional.
Los modificadores de tamaño de inserción también evitan usar la misma porción de inserciones más de una vez si ya se consumieron. Sin embargo, como cambian su tamaño directamente, no consumen inserciones.
Como resultado, los modificadores de padding anidados cambian automáticamente la cantidad de padding que se aplica a cada elemento componible.
Si observamos el mismo ejemplo de LazyColumn que antes, el modificador imePadding cambia el tamaño de LazyColumn. Dentro de LazyColumn, el último elemento se dimensiona para que tenga la altura de la parte inferior de las barras del sistema:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Cuando el IME está cerrado, el modificador imePadding() no aplica relleno, ya que el IME no tiene altura. Como el modificador imePadding() no aplica relleno, no se consumen inserciones, y la altura del Spacer será el tamaño del lado inferior de las barras del sistema.
Cuando se abre el IME, las inserciones del IME se animan para que coincidan con el tamaño del IME, y el modificador imePadding() comienza a aplicar padding inferior para cambiar el tamaño del LazyColumn a medida que se abre el IME. A medida que el modificador imePadding() comienza a aplicar el padding inferior, también comienza a consumir esa cantidad de inserciones. Por lo tanto, la altura de Spacer comienza a disminuir, ya que el modificador imePadding() ya aplicó parte del espaciado para las barras del sistema. Una vez que el modificador imePadding() aplica una cantidad de padding inferior que es mayor que las barras del sistema, la altura de Spacer es cero.
Cuando se cierra el IME, los cambios se producen en sentido inverso: el Spacer comienza a expandirse desde una altura de cero una vez que el imePadding() aplica menos que el lado inferior de las barras del sistema, hasta que finalmente el Spacer coincide con la altura del lado inferior de las barras del sistema una vez que el IME se cierra por completo con la animación.
TextField.Este comportamiento se logra a través de la comunicación entre todos los modificadores de windowInsetsPadding y se puede influir en él de otras maneras.
Modifier.consumeWindowInsets(insets: WindowInsets) también consume inserciones de la misma manera que Modifier.windowInsetsPadding, pero no aplica las inserciones consumidas como padding. Esto es útil en combinación con los modificadores de tamaño de inserción, para indicar a los elementos secundarios que ya se consumió una cierta cantidad de inserciones:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues) se comporta de manera muy similar a la versión con un argumento WindowInsets, pero toma un PaddingValues arbitrario para consumir. Esto es útil para informar a los elementos secundarios cuando se proporciona relleno o espaciado a través de algún otro mecanismo que no sean los modificadores de relleno de inserción, como un Modifier.padding común o espaciadores de altura fija:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
En los casos en los que se necesiten las inserciones de ventana sin procesar sin consumo, usa los valores de WindowInsets directamente o usa WindowInsets.asPaddingValues() para devolver un PaddingValues de las inserciones que no se ven afectadas por el consumo.
Sin embargo, debido a las siguientes advertencias, es preferible usar los modificadores de padding de WindowInsets y los modificadores de tamaño de WindowInsets siempre que sea posible.
Inserciones y fases de Jetpack Compose
Compose usa las APIs principales subyacentes de AndroidX para actualizar y animar las inserciones, que usan las APIs de la plataforma subyacentes que administran las inserciones. Debido al comportamiento de esa plataforma, las inserciones tienen una relación especial con las fases de Jetpack Compose.
Los valores de las inserciones se actualizan después de la fase de composición, pero antes de la fase de diseño. Esto significa que, por lo general, la lectura del valor de las inserciones en la composición usa un valor de las inserciones que se retrasa un fotograma. Los modificadores integrados que se describen en esta página se compilan para retrasar el uso de los valores de las inserciones hasta la fase de diseño, lo que garantiza que los valores de inserción se usen en el mismo fotograma en el que se actualizan.