Pour permettre à votre application de contrôler entièrement l'emplacement où elle dessine le contenu, suivez ces étapes de configuration. Sans ces étapes, votre application peut dessiner des couleurs noires ou unies derrière l'UI système, ou ne pas s'animer de manière synchrone avec le clavier logiciel.
- Ciblez Android 15 (niveau d'API 35) ou version ultérieure pour appliquer le mode bord à bord sur Android 15 et versions ultérieures. Votre application s'affiche derrière l'UI système. Vous pouvez ajuster l'interface utilisateur de votre application en gérant les encarts.
- Vous pouvez également appeler
enableEdgeToEdge()
dansActivity.onCreate()
, ce qui permet à votre application d'être bord à bord sur les versions précédentes d'Android. Définissez
android:windowSoftInputMode="adjustResize"
dans l'entréeAndroidManifest.xml
de votre activité. Ce paramètre permet à votre application de recevoir la taille de l'IME logiciel sous forme d'encarts, ce qui vous aide à appliquer la mise en page et la marge intérieure appropriées lorsque l'IME apparaît et disparaît dans votre application.<!-- In your AndroidManifest.xml file: --> <activity android:name=".ui.MainActivity" android:label="@string/app_name" android:windowSoftInputMode="adjustResize" android:theme="@style/Theme.MyApplication" android:exported="true">
Utiliser les API Compose
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 système. Ces API synchronisent également la mise en page de votre application avec les modifications des encarts.
Par exemple, voici la méthode la plus élémentaire 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
en tant que 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 système, mais cela signifie également qu'aucune partie de l'application ne s'affichera derrière l'UI système pour obtenir un effet bord à bord. Pour exploiter pleinement toute la fenêtre, vous devez ajuster précisément l'emplacement des encarts, écran par écran ou composant par composant.
Tous ces types d'encarts sont animés automatiquement avec les 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 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 encarts de dessin sécurisés en tant que marge intérieure sur les quatre côtés.
Il existe également plusieurs méthodes utilitaires intégrées pour les types d'encarts les plus courants.
Modifier.safeDrawingPadding()
est l'une de ces méthodes, équivalente à Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
. Il existe des modificateurs analogues pour les autres types d'encarts.
Modificateurs de taille d'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é de fin de windowInsets comme largeur (comme |
|
Applique le côté supérieur 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'encart
Les modificateurs de marge intérieure (windowInsetsPadding
et les assistants tels que safeDrawingPadding
) consomment automatiquement la partie des encarts qui est appliquée 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 de marge intérieure savent qu'une partie des marges intérieures a déjà été utilisée par les modificateurs de marge intérieure externes. Ils évitent ainsi d'utiliser la même partie des marges intérieures plusieurs fois, ce qui entraînerait un espace supplémentaire trop important.
Les modificateurs de taille d'encart évitent également d'utiliser la même partie des encarts plusieurs fois si les encarts ont déjà été utilisés. Toutefois, comme ils modifient directement leur taille, ils ne consomment pas eux-mêmes les encarts.
Par conséquent, l'imbrication des modificateurs de marge intérieure modifie automatiquement la marge intérieure appliquée à chaque composable.
En reprenant le même exemple LazyColumn
que précédemment, la taille de LazyColumn
est modifiée par le modificateur imePadding
. Dans LazyColumn
, la taille du dernier élément correspond à la hauteur de la partie inférieure 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 marge n'est utilisée et la hauteur de Spacer
correspond à la taille du côté inférieur des barres système.
Lorsque l'IME s'ouvre, les encarts IME s'animent pour correspondre à la taille de l'IME, et le modificateur imePadding()
commence à appliquer une marge intérieure inférieure pour redimensionner LazyColumn
à mesure que l'IME s'ouvre. À mesure que le modificateur imePadding()
commence à appliquer un espacement intérieur en bas, il commence également à consommer cette quantité d'encarts. 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 à celle des barres système, la hauteur de Spacer
est nulle.
Lorsque l'IME se ferme, les modifications se produisent en sens inverse : le Spacer
commence à se développer à partir d'une hauteur nulle une fois que le imePadding()
applique moins que le côté inférieur des barres système, jusqu'à ce que le Spacer
corresponde à la hauteur du côté inférieur des barres système une fois que l'IME est complètement animé.
TextField
.Ce comportement est obtenu grâce à la communication entre tous les modificateurs windowInsetsPadding
et peut être influencé de plusieurs autres manières.
Modifier.consumeWindowInsets(insets: WindowInsets)
consomme également les encarts de la même manière que Modifier.windowInsetsPadding
, mais il n'applique pas les encarts consommés en tant que marge intérieure. Cela est utile en combinaison avec les modificateurs de taille d'encart, pour indiquer aux éléments frères 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 sont fournis 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)) }
Dans les cas où les encarts de fenêtre bruts sont nécessaires sans consommation, utilisez directement les valeurs WindowInsets
ou utilisez WindowInsets.asPaddingValues()
pour renvoyer un PaddingValues
des encarts qui ne sont pas affectés par la consommation.
Toutefois, en raison des mises en garde suivantes, préférez utiliser les modificateurs de marge intérieure et de taille des encarts de fenêtre dans la mesure du possible.
Encarts et phases de Jetpack Compose
Compose utilise les API Core AndroidX sous-jacentes pour mettre à jour et animer les encarts, qui utilisent les API de plate-forme sous-jacentes gérant les encarts. En raison de ce comportement de plate-forme, les encarts ont une relation particulière avec les phases de Jetpack Compose.
La valeur des encarts 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 en retard d'une frame. Les modificateurs intégrés décrits sur cette page sont conçus pour retarder l'utilisation des valeurs des encarts jusqu'à la phase de mise en page, ce qui garantit que les valeurs des encarts sont utilisées sur le même frame que celui sur lequel elles sont mises à jour.