Une fois que votre activité a pris le contrôle de la gestion de tous les encarts, vous pouvez utiliser les API Compose pour vous assurer que le contenu n'est pas masqué et que les éléments interactifs ne se chevauchent pas avec l'UI du système. Ces API synchronisent également la mise en page de votre application avec les modifications de l'encart.
Par exemple, voici la méthode la plus simple pour appliquer les encarts au contenu de l'ensemble de votre application:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Cet extrait applique les encarts de fenêtre safeDrawing
comme marge intérieure autour de l'ensemble du contenu de l'application. Cela garantit que les éléments interactifs ne se chevauchent pas avec l'UI du système, mais cela signifie également qu'aucun élément de l'application ne sera dessiné derrière l'UI du système pour obtenir un effet bord à bord. Pour exploiter pleinement l'ensemble de la fenêtre, vous devez affiner l'emplacement des encarts par écran ou par composant.
Tous ces types d'encarts sont animés automatiquement avec des animations IME rétroportées vers l'API 21. Par extension, toutes vos mises en page utilisant ces encarts sont également animées automatiquement lorsque les valeurs d'encart changent.
Il existe deux principales façons d'utiliser ces types d'encarts pour ajuster vos mises en page de composables: les modificateurs de marge intérieure et les modificateurs de taille d'encart.
Modificateurs de marge intérieure
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
applique les encarts de fenêtre donnés en tant que marge intérieure, comme le ferait Modifier.padding
.
Par exemple, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
applique les marges intérieures de dessin sécurisées en tant que marge intérieure sur les quatre côtés.
Plusieurs méthodes utilitaires intégrées sont également disponibles pour les types d'encarts les plus courants.
Modifier.safeDrawingPadding()
est une telle méthode, équivalente à Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
. Il existe des modificateurs analogues pour les autres types d'encarts.
Modificateurs de taille de l'encart
Les modificateurs suivants appliquent une quantité d'encarts de fenêtre en définissant la taille du composant sur la taille des encarts:
Applique le côté de début de windowInsets comme largeur (comme |
|
Applique le côté final de windowInsets comme largeur (comme |
|
Applique la partie supérieure de windowInsets comme hauteur (comme |
|
|
Applique la partie inférieure de windowInsets comme hauteur (comme |
Ces modificateurs sont particulièrement utiles pour dimensionner un Spacer
qui occupe l'espace des encarts:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consommation d'incrustations
Les modificateurs de marge intérieure (windowInsetsPadding
et les outils d'assistance tels que safeDrawingPadding
) consomment automatiquement la partie des marges intérieures appliquées en tant que marge intérieure. En approfondissant l'arborescence de composition, les modificateurs de marge intérieure imbriqués et les modificateurs de taille d'encart savent qu'une partie des encarts a déjà été utilisée par les modificateurs de marge intérieure externe, et évitent d'utiliser la même partie des encarts plusieurs fois, ce qui entraînerait trop d'espace supplémentaire.
Les modificateurs de taille d'encart évitent également d'utiliser la même partie d'encart plusieurs fois si les encarts ont déjà été consommés. Toutefois, comme ils modifient directement leur taille, ils ne consomment pas eux-mêmes d'encarts.
Par conséquent, les modificateurs de marge intérieure imbriqués modifient automatiquement la quantité de marge intérieure appliquée à chaque composable.
En examinant le même exemple LazyColumn
qu'auparavant, le LazyColumn
est redimensionné par le modificateur imePadding
. Dans LazyColumn
, la taille du dernier élément correspond à la hauteur du bas des barres système:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Lorsque l'IME est fermé, le modificateur imePadding()
n'applique aucune marge intérieure, car l'IME n'a pas de hauteur. Étant donné que le modificateur imePadding()
n'applique aucune marge intérieure, aucune encoche n'est consommée, et la hauteur de Spacer
correspond à la taille de la partie inférieure des barres système.
Lorsque l'IME s'ouvre, les encarts de l'IME s'animent pour correspondre à la taille de l'IME, et le modificateur imePadding()
commence à appliquer une marge intérieure inférieure pour redimensionner le LazyColumn
lorsque l'IME s'ouvre. Lorsque le modificateur imePadding()
commence à appliquer la marge inférieure, il commence également à consommer cette quantité de marges intérieures. Par conséquent, la hauteur de Spacer
commence à diminuer, car une partie de l'espacement des barres système a déjà été appliquée par le modificateur imePadding()
. Une fois que le modificateur imePadding()
applique une marge intérieure inférieure supérieure aux barres système, la hauteur de Spacer
est nulle.
Lorsque l'IME se ferme, les modifications se produisent dans l'ordre inverse: Spacer
commence à se développer à partir d'une hauteur de zéro une fois que imePadding()
s'applique moins que la partie inférieure des barres système, jusqu'à ce que Spacer
corresponde à la hauteur de la partie inférieure des barres système une fois que l'IME est complètement animé.
TextField
.Ce comportement est obtenu par la communication entre tous les modificateurs windowInsetsPadding
et peut être influencé de plusieurs autres manières.
Modifier.consumeWindowInsets(insets: WindowInsets)
consomme également des encarts de la même manière que Modifier.windowInsetsPadding
, mais n'applique pas les encarts consommés en tant que marge intérieure. Cela est utile en combinaison avec les modificateurs de taille des encarts pour indiquer aux frères et sœurs qu'une certaine quantité d'encarts a déjà été consommée:
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 comporte de manière très similaire à la version avec un argument WindowInsets
, mais prend un PaddingValues
arbitraire à consommer. Cela permet d'informer les enfants lorsque la marge intérieure ou l'espacement est fourni par un autre mécanisme que les modificateurs de marge intérieure, tels qu'un Modifier.padding
ordinaire ou des espaces de hauteur fixe:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Lorsque les encarts de fenêtre bruts sont nécessaires sans consommation, utilisez directement les valeurs WindowInsets
ou WindowInsets.asPaddingValues()
pour renvoyer un PaddingValues
des encarts non affectés par la consommation.
Toutefois, en raison des mises en garde ci-dessous, préférez utiliser les modificateurs de marge intérieure et de taille des encarts de fenêtre dans la mesure du possible.
Insets et phases de Jetpack Compose
Compose utilise les API principales AndroidX sous-jacentes pour mettre à jour et animer les insets, qui utilisent les API de plate-forme sous-jacentes qui gèrent les insets. En raison de ce comportement de la plate-forme, les encarts ont une relation particulière avec les phases de Jetpack Compose.
La valeur des marges intérieures est mise à jour après la phase de composition, mais avant la phase de mise en page. Cela signifie que la lecture de la valeur des encarts dans la composition utilise généralement une valeur des encarts qui est retardée d'un frame. Les modificateurs intégrés décrits sur cette page sont conçus pour retarder l'utilisation des valeurs des marges intérieures jusqu'à la phase de mise en page, ce qui garantit que les valeurs de marge intérieure sont utilisées sur le même frame qu'elles sont mises à jour.