La plate-forme Android est chargée de dessiner l'UI du système, par exemple la barre d'état et la barre de navigation. Cette UI du système s'affiche quelle que soit l'application que l'utilisateur utilise.
WindowInsets
fournit des informations sur le système.
UI pour s'assurer que votre application s'affiche dans la bonne zone et qu'elle n'est pas masquée
par l'UI du système.
![Affichage bord à bord pour dessiner derrière les barres système](https://developer.android.google.cn/static/develop/ui/compose/images/layouts/insets/e2e-intro.gif?authuser=9&hl=fr)
Sur Android 14 (niveau d'API 34) ou version antérieure, l'interface utilisateur de votre application ne s'affiche pas en dessous. les barres système et les encoches par défaut.
Sur Android 15 (niveau d'API 35) ou version ultérieure, votre application s'affiche sous le système. barres et encoches une fois que votre application cible le SDK 35. Vous bénéficiez ainsi d'une une expérience utilisateur fluide et permet à votre application de tirer pleinement parti l'espace de fenêtre disponible.
Le contenu affiché derrière l'interface utilisateur du système est appelé bord à bord. Sur ce page, vous découvrirez les différents types d'encarts, comment passer de bord à bord, et comment utiliser les API d'encart pour animer votre interface utilisateur et vous assurer que le contenu de votre application n'est pas masquée par les éléments d'UI du système.
Principes de base des encarts
Lorsqu'une application s'affiche de bord à bord, vous devez vous assurer que le contenu et les interactions ne sont pas masquées par l'UI du système. Par exemple, si un bouton est placée derrière la barre de navigation, l’utilisateur risque de ne pas pouvoir cliquer dessus.
la taille de l'UI du système et des informations sur son emplacement sont spécifiés ; via des encarts.
Chaque partie de l'UI du système possède un type d'encart correspondant qui décrit sa taille et son emplacement. Par exemple, les encarts de la barre d'état indiquent la taille et la position de la barre d'état, tandis que les encarts de la barre de navigation fournissent la taille et la position de la barre de navigation. Chaque type d'encart se compose de quatre dimensions en pixels: haut, gauche, droite et bas. Ces dimensions indiquent dans quelle mesure l'UI du système s'étend des côtés correspondants de la fenêtre de l'application. Pour éviter chevauchant ce type d'UI du système, l'UI de l'application doit donc être insérée montant.
Ces types d'encarts Android intégrés sont disponibles via WindowInsets
:
Encarts décrivant les barres d'état. Les barres supérieures de l'interface utilisateur du système contiennent les icônes de notification et d'autres indicateurs. |
|
La barre d'état apparaît en médaillons lorsque ces éléments sont visibles. Si les barres d'état sont actuellement masquées (en raison du passage en mode immersif en plein écran), les encarts de la barre d'état principale seront vides, mais ils ne le seront pas. |
|
Encarts décrivant les barres de navigation. Il s'agit des barres d'UI du système à gauche, à droite ou en bas de l'appareil. Elles décrivent la barre des tâches ou les icônes de navigation. Ceux-ci peuvent changer au moment de l'exécution en fonction de la méthode de navigation préférée de l'utilisateur et de l'interaction avec la barre des tâches. |
|
La barre de navigation s'insère dans des encarts pour indiquer quand ils sont visibles. Si les barres de navigation sont actuellement masquées (en raison du passage en mode immersif en plein écran), les encarts de la barre de navigation principale seront vides, mais ils ne le seront pas. |
|
Encart décrivant la décoration de la fenêtre de l'UI du système s'il se trouve dans une fenêtre de forme libre, comme la barre de titre supérieure. |
|
La barre de sous-titres est encadrée pour indiquer quand ils sont visibles. Si les barres de sous-titres sont actuellement masquées, les encarts de la barre de sous-titres principale seront vides, mais ils le seront. |
|
L'union des encarts de la barre système, qui comprend les barres d'état, les barres de navigation et la barre de sous-titres. |
|
La barre système s'affiche en médaillons pour indiquer qu'ils sont visibles. Si les barres système sont actuellement masquées (en raison du passage en mode immersif en plein écran), les encarts de la barre système principale seront vides, mais ils ne le seront pas. |
|
Encarts décrivant l'espace en bas que le clavier virtuel occupe. |
|
Encarts décrivant l'espace occupé par le clavier virtuel avant l'animation actuelle du clavier. |
|
Encarts décrivant l'espace que le clavier virtuel occupera après l'animation actuelle du clavier. |
|
Type d'encarts décrivant des informations plus détaillées sur l'interface utilisateur de navigation, donnant la quantité d'espace où des « appuis » seront gérés par le système, et non par l'application. Pour les barres de navigation transparentes avec navigation par gestes, il est possible d'appuyer sur certains éléments de l'application via l'UI de navigation du système. |
|
Encarts d'élément tactiles qui s'affichent lorsque ceux-ci sont visibles. Si les éléments tactiles sont actuellement masqués (en raison du passage en mode immersif en plein écran), les encarts principaux des éléments tactiles seront vides, mais ils ne le seront pas. |
|
Encarts représentant le nombre d'encarts où le système intercepte les gestes de navigation. Les applications peuvent spécifier manuellement la gestion d'un nombre limité de ces gestes via |
|
Sous-ensemble de gestes système qui seront toujours gérés par le système et qui ne peuvent pas être désactivés via |
|
Les encarts représentant l'espacement nécessaire pour éviter de chevaucher une encoche (encoche ou trou d'épingle). |
|
Encarts représentant les zones incurvées d'une cascade. Un écran en cascade présente des zones incurvées le long des bords de l'écran, là où celui-ci commence à s'enrouler sur les côtés de l'appareil. |
Ces types sont résumés par trois catégories d'encarts pour s'assurer que le contenu n'est pas masquées:
Ces "sécurisés" types d'encarts protègent le contenu de différentes manières, en fonction encarts de plate-forme sous-jacents:
- Utilisez
WindowInsets.safeDrawing
pour protéger le contenu qui ne doit pas être dessiné. sous n'importe quelle UI du système. Il s'agit de l'utilisation la plus courante des encarts: pour éviter en dessinant du contenu obscurci par l'interface utilisateur du système (que ce soit partiellement ou complètement). - Utilisez
WindowInsets.safeGestures
pour protéger des contenus à l'aide de gestes. Ce évite les conflits entre les gestes système et les gestes de l'application (tels que ceux les feuilles, les carrousels ou les jeux). - Utilisez
WindowInsets.safeContent
en combinaison deWindowInsets.safeDrawing
etWindowInsets.safeGestures
pour vous assurer le contenu ne se superpose pas aux visuels ni aux gestes.
Configuration des encarts
Pour donner à votre application un contrôle total sur l'emplacement où elle dessine le contenu, procédez comme suit : étapes. Sans ces étapes, votre application risque de dessiner des couleurs noires ou unies derrière le ou ne pas s'animer de manière synchrone avec le clavier virtuel.
- Ciblez le SDK 35 ou version ultérieure pour appliquer de bord à bord sur Android 15 ou version ultérieure. Votre application s'affiche derrière l'UI du système. Vous pouvez ajuster l'UI de votre application encarts.
- Vous pouvez également appeler
enableEdgeToEdge()
dansActivity.onCreate()
, qui permet à votre application d'être bord à bord par rapport aux Versions d'Android Définir
android:windowSoftInputMode="adjustResize"
dans le EntréeAndroidManifest.xml
. Ce paramètre permet à votre application de recevoir la taille de l'IME du logiciel sous forme d'encarts, que vous pouvez utiliser pour remplir et mettre en page le contenu correctement 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">
API Compose
Une fois que votre activité a pris le contrôle de la gestion de tous les encarts, vous pouvez utiliser Compose des API pour s'assurer que le contenu n'est pas obscurci et que les éléments interactifs ne sont pas qui se chevauchent avec l'UI du système. Ces API synchronisent également la mise en page de votre application avec les modifications d'encart.
Par exemple, il s'agit de la méthode la plus basique 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 la fenêtre safeDrawing
en tant que marge intérieure autour de
l'intégralité du contenu de l'application. Bien que cela garantit que les éléments
interactifs n’ont pas
avec l'UI du système, cela signifie aussi qu'aucune application
pour obtenir un effet bord à bord. Pour exploiter pleinement l'ensemble
vous devez ajuster l'emplacement des encarts dans un écran par écran.
composant par composant.
Tous ces types d'encarts sont animés automatiquement avec des animations IME rétroportée vers l'API 21. Par extension, toutes vos mises en page utilisant ces encarts sont automatiquement animée lorsque les valeurs d'encart changent.
Il existe deux façons principales d'utiliser ces types d'encarts pour ajuster votre composable. mises en page: modificateurs de marge intérieure et de taille d'encart.
Modificateurs de marge intérieure
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
applique les
des encarts de fenêtre donnés comme marge intérieure, comme le ferait Modifier.padding
.
Par exemple, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
s'applique
les encarts de dessin sûrs
comme marges intérieures sur les 4 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. Elle équivaut à
Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
Il existe des exemples
des modificateurs pour les
autres types d’encarts.
Modificateurs de taille d'encart
Les modificateurs suivants appliquent un certain nombre d'encarts de fenêtre en définissant la taille le composant à la taille des encarts:
Applique le côté de début de windowInsets en tant que largeur (comme |
|
Applique la fin des encarts windowInsets en tant que largeur (comme |
|
Applique la partie supérieure des encarts windowInsets en tant que hauteur (comme |
|
|
Applique la partie inférieure des encarts windowInsets en tant que hauteur (comme |
Ces modificateurs sont particulièrement utiles pour dimensionner une Spacer
qui occupe
d'encarts:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consommation d'encarts
Les modificateurs de marge intérieure (windowInsetsPadding
et les assistants tels que
safeDrawingPadding
) consomment automatiquement la partie des encarts
appliqué comme remplissage. Pour approfondir l'arborescence de composition, l'encart imbriqué
les modificateurs de marge intérieure et les modificateurs de taille d'encart savent qu'une partie
les encarts sont déjà utilisés par les modificateurs de marge intérieure d'encart externes, et évitez
utiliser la même partie des encarts
plusieurs fois, ce qui entraînerait trop
beaucoup plus d'espace supplémentaire.
Les modificateurs de taille d'encart évitent également d'utiliser la même partie des encarts plusieurs fois. si des encarts ont déjà été utilisés. Cependant, puisqu'ils sont en train de changer les encarts ne sont pas directement utilisés.
Par conséquent, l'imbrication des modificateurs de marge intérieure modifie automatiquement la quantité une marge intérieure appliquée à chaque composable.
Si nous observons le même exemple LazyColumn
qu'auparavant, LazyColumn
est en cours
redimensionnée par le modificateur imePadding
. Dans LazyColumn
, le dernier élément est
adapté à 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,
et aucun encart n'est utilisé, et la hauteur de Spacer
correspond à la taille
le côté inférieur des
barres système.
À l'ouverture de l'IME, les encarts s'animent pour correspondre à la taille de l'IME et
Le modificateur imePadding()
commence à appliquer une marge intérieure inférieure pour redimensionner la
LazyColumn
à l'ouverture de l'IME. Lorsque le modificateur imePadding()
commence à s'appliquer
une marge intérieure inférieure, il commence également à consommer cette quantité d'encarts. Par conséquent, le
la hauteur de Spacer
commence à diminuer pour l'espacement du système.
barres ont déjà été appliquées par le modificateur imePadding()
. Une fois que
Le modificateur imePadding()
applique une marge intérieure inférieure plus importante
que les barres système, la hauteur de Spacer
est égale à zéro.
Lorsque l'IME se ferme, les modifications se produisent à l'envers: Spacer
commence à
à partir d'une hauteur de zéro une fois que imePadding()
applique moins que
en bas des barres système, jusqu'à ce que Spacer
corresponde à la hauteur
le 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 peuvent être influencés dans d'autres
de différentes manières.
Modifier.consumeWindowInsets(insets: WindowInsets)
utilise également des encarts.
de la même manière que pour Modifier.windowInsetsPadding
, mais elle ne s'applique pas
des encarts consommés comme remplissage. Ceci est utile en combinaison avec l’encart
des modificateurs de taille, pour indiquer aux frères et sœurs qu'un certain nombre d'encarts
déjà consommées:
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)) }
Le comportement de Modifier.consumeWindowInsets(paddingValues: PaddingValues)
est très élevé.
de la même manière que la version avec un argument WindowInsets
, mais prend une
PaddingValues
arbitraires à utiliser. Cela est utile pour informer
lorsque le remplissage ou l'espacement est fourni par un autre mécanisme que
des modificateurs de marge intérieure, tels qu'un élément Modifier.padding
ordinaire ou une hauteur fixe ;
entretoises:
@OptIn(ExperimentalLayoutApi::class) 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 la
WindowInsets
directement, ou utilisez WindowInsets.asPaddingValues()
pour
renvoient un PaddingValues
des encarts qui ne sont pas affectés par la consommation.
Toutefois, en raison des mises en garde ci-dessous, il est préférable d'utiliser la marge intérieure des encarts de la fenêtre.
et des modificateurs de taille d'encarts de fenêtre autant que possible.
Phases d'encarts et de Jetpack Compose
Compose utilise les API principales sous-jacentes d'AndroidX pour mettre à jour et animer les encarts, qui utilisent les API sous-jacentes de la plate-forme qui gèrent les encarts. Grâce à cette plate-forme, le comportement des encarts, les encarts ont une relation particulière avec les phases de Jetpack Nouveau message.
La valeur des encarts est mise à jour après la phase de composition, mais avant la phase 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 d'encarts qui a un frame en retard. L'API décrits sur cette page sont conçus pour retarder l'utilisation des valeurs du paramètre encarts jusqu'à la phase de mise en page, ce qui garantit que les valeurs d'encart sont utilisées sur dans le même cadre quand elles sont mises à jour.
Animations IME du clavier avec WindowInsets
Vous pouvez appliquer Modifier.imeNestedScroll()
à un conteneur à défilement pour ouvrir et
fermer automatiquement l'IME lors du défilement jusqu'au bas du conteneur.
class WindowInsetsExampleActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { MaterialTheme { MyScreen() } } } } @OptIn(ExperimentalLayoutApi::class) @Composable fun MyScreen() { Box { LazyColumn( modifier = Modifier .fillMaxSize() // fill the entire window .imePadding() // padding for the bottom for the IME .imeNestedScroll(), // scroll IME at the bottom content = { } ) FloatingActionButton( modifier = Modifier .align(Alignment.BottomEnd) .padding(16.dp) // normal 16dp of padding for FABs .navigationBarsPadding() // padding for navigation bar .imePadding(), // padding for when IME appears onClick = { } ) { Icon(imageVector = Icons.Filled.Add, contentDescription = "Add") } } }
![Animation montrant un élément d'interface utilisateur glissant vers le haut ou vers le bas pour laisser place à un clavier](https://developer.android.google.cn/static/develop/ui/compose/images/interop-keyboard.gif?authuser=9&hl=fr)
Compatibilité des encarts avec les composants Material 3
Pour plus de simplicité, de nombreux composables Material 3 intégrés
(androidx.compose.material3
)
gérer les encarts eux-mêmes, en fonction de la manière dont les composables sont placés dans votre application.
conformément aux spécifications de Material.
Gestion des composables de l'encart
Vous trouverez ci-dessous la liste des ressources des composants gèrent automatiquement les encarts.
Barres d'application
TopAppBar
/SmallTopAppBar
/CenterAlignedTopAppBar
/MediumTopAppBar
/LargeTopAppBar
: applique les côtés supérieurs et horizontaux des barres système en tant que marge intérieure, car elle est utilisée en haut de la fenêtre.BottomAppBar
: applique les côtés bas et horizontal des barres système en tant que marge intérieure.
Conteneurs
ModalDrawerSheet
/DismissibleDrawerSheet
/PermanentDrawerSheet
(contenu dans un panneau de navigation modal): applique des encarts vertical et début au contenu.ModalBottomSheet
: Applique les encarts bas.NavigationBar
: applique les encarts inférieurs et horizontaux.NavigationRail
: applique les encarts vertical et start.
Scaffold
Par défaut,
Scaffold
fournit des encarts en tant que paramètre paddingValues
que vous pouvez consommer et utiliser.
Scaffold
n'applique pas les encarts au contenu. cette responsabilité vous incombe.
Par exemple, pour utiliser ces encarts avec un LazyColumn
dans un Scaffold
:
Scaffold { innerPadding -> // innerPadding contains inset information for you to use and apply LazyColumn( // consume insets as scaffold doesn't do it by default modifier = Modifier.consumeWindowInsets(innerPadding), contentPadding = innerPadding ) { items(count = 100) { Box( Modifier .fillMaxWidth() .height(50.dp) .background(colors[it % colors.size]) ) } } }
Remplacer les encarts par défaut
Vous pouvez remplacer le paramètre windowInsets
transmis au composable par
configurer le comportement du composable. Ce paramètre peut être un autre type
encart de fenêtre à appliquer à la place, ou désactivé en transmettant une instance vide:
WindowInsets(0, 0, 0, 0)
Par exemple, pour désactiver le traitement des encarts sur
LargeTopAppBar
,
définissez le paramètre windowInsets
sur une instance vide:
LargeTopAppBar( windowInsets = WindowInsets(0, 0, 0, 0), title = { Text("Hi") } )
Interopérabilité avec les encarts du système de vues
Vous devrez peut-être remplacer les encarts par défaut si votre écran dispose à la fois de vues et Code Compose dans la même hiérarchie. Dans ce cas, vous devez être explicite dans qui doit utiliser les encarts ou qui doit les ignorer.
Par exemple, si votre mise en page externe est une mise en page Android View, vous devez
utiliser les encarts dans le système de vues et les ignorer pour Compose.
Si votre mise en page externe est un composable, vous devez utiliser la classe
encarts dans Compose et remplir les composables AndroidView
en conséquence.
Par défaut, chaque ComposeView
consomme tous les encarts au
Niveau de consommation de WindowInsetsCompat
. Pour modifier ce comportement par défaut, définissez
ComposeView.consumeWindowInsets
à false
.
Ressources
- Now in Android : une application Android entièrement fonctionnelle, conçue entièrement avec Kotlin et Jetpack Compose.
- Gérer les mesures d'application bord à bord dans Android 15 : atelier de programmation présentant l'application bord à bord d'Android 15
- 3 choses pour améliorer votre expérience avec les applications Android : Edge to Edge, Predictive Back et Glance : une vidéo YouTube évoquant l'application bord à bord d'Android 15.
- Bord à bord et encarts | Conseils de rédaction : une vidéo YouTube montrant comment gérer les encarts pour dessiner bord à bord.
Recommandations personnalisées
- Remarque : Le texte du lien s'affiche lorsque JavaScript est désactivé
- Composants et mises en page Material
- Migrer
CoordinatorLayout
vers Compose - Autres points à prendre en compte