waser-rao/kmp-edge-to-edge

Disposition edge-to-edge dans Compose Multiplatform pour Android et iOS - activation par plateforme, WindowInsets avec Scaffold, listes, barres inférieures, clavier (IME), découpes d'écran, contraste des icônes de la barre système et bannières publicitaires en bord d'écran. À utiliser lors de la construction de tout écran avec scaffold, pour corriger le contenu caché derrière la barre d'état, la barre de navigation, l'encoche ou le clavier, ou pour cibler Android 15 et versions ultérieures.

Qu'est-ce que kmp-edge-to-edge ?

Cette compétence fournit une approche structurée pour implémenter le mode edge-to-edge dans les applications Compose Multiplatform, en garantissant que le contenu s'affiche correctement sous les barres système sur Android et iOS. Elle explique comment activer l'edge-to-edge sur Android via `enableEdgeToEdge()` dans l'activité, et sur iOS en utilisant `ignoresSafeArea()` sur la vue SwiftUI. La compétence détaille l'utilisation de `Scaffold` et de `WindowInsets` pour gérer les barres d'état, de navigation, les découpes d'écran et le clavier, tout en évitant les doublons de padding. Elle couvre également le contenu plein écran (images, vidéos), le contraste des icônes des barres système, les bannières publicitaires et fournit une checklist complète pour chaque écran. Idéale pour les développeurs utilisant Compose Multiplatform sur Android et iOS, cette compétence permet de respecter les nouvelles exigences de Google à partir de l'API 35 et d'offrir une expérience utilisateur optimale.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/wasey-rao/kmp-agent-studio/tree/HEAD/kmp-studio/skills/kmp-edge-to-edge

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Edge-to-edge dans Compose Multiplatform

Android impose l'edge-to-edge pour les applications ciblant SDK 35 et ultérieur, et l'option de désactivation disparaît à partir de 36. Les applications iOS sont censées s'afficher sous la barre d'état et l'indicateur d'accueil. Construisez chaque écran en mode edge-to-edge dès le début.

La règle : les arrière-plans s'affichent derrière les barres système ; le contenu et les contrôles sont décalés par les insets.

Activer l'edge-to-edge

Android (MainActivity dans androidApp), avant setContent :

override fun onCreate(savedInstanceState: Bundle?) {
    enableEdgeToEdge()
    super.onCreate(savedInstanceState)
    setContent { App() }
}

Dans le manifeste, définissez android:windowSoftInputMode="adjustResize" sur l'activité pour que les insets IME atteignent Compose.

iOS (ContentView.swift) : laissez Compose occuper tout l'écran, sinon SwiftUI applique les zones de sécurité d'abord et Compose voit zéro inset.

ComposeView().ignoresSafeArea()

Scaffold fait la majeure partie du travail

Scaffold(
    topBar = { TopAppBar(title = { Text(title) }) },          // se décale automatiquement pour la barre d'état
    bottomBar = { NavigationBar { /* ... */ } },              // se décale automatiquement pour la barre de navigation
) { innerPadding ->
    LazyColumn(
        contentPadding = innerPadding,                         // le contenu défile sous les barres
        modifier = Modifier.fillMaxSize(),
    ) { /* éléments */ }
}
  • Utilisez toujours innerPadding. Pour les listes, passez-le en tant que contentPadding pour que les éléments défilent derrière les barres translucides ; pour le contenu non défilant, utilisez Modifier.padding(innerPadding).
  • Les barres Material 3 consomment leurs propres insets. N'ajoutez pas statusBarsPadding() par-dessus une TopAppBar.
  • Les Scaffolds imbriqués doublent le padding. Donnez au scaffold intérieur contentWindowInsets = WindowInsets(0) ou appliquez consumeWindowInsets(innerPadding) sur le contenu extérieur.

Écrans sans Scaffold

Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) {   // l'arrière-plan remplit l'écran
    Column(Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing)) { /* contenu */ }
}

WindowInsets.safeDrawing couvre la barre d'état, la barre de navigation, la découpe d'écran et le clavier. Utilisez safeContent lorsque les gestes sont importants. Appliquez le padding des insets une seule fois, au niveau qui possède le contenu, jamais à la fois sur le parent et l'enfant.

Clavier

  • Écrans de saisie : Modifier.imePadding() sur le conteneur défilant, ou safeDrawing qui inclut déjà l'IME.
  • Un bouton en bas qui doit rester au-dessus du clavier : placez-le dans le bottomBar du scaffold avec Modifier.imePadding(), ou utilisez WindowInsets.ime.union(WindowInsets.navigationBars).
  • Rendez le contenu défilant pour qu'un champ focalisé puisse apparaître à l'écran.

Contenu plein écran

Les images, cartes, vidéos et aperçus de caméra doivent ignorer les insets et remplir l'écran. Superposez les contrôles par-dessus et ne décalez que les contrôles avec WindowInsets.safeDrawing.

Contraste des icônes de la barre système

Les barres sont transparentes, donc le contraste des icônes est votre responsabilité. Sur Android, enableEdgeToEdge() choisit des icônes claires ou sombres en fonction du thème système ; si l'application a son propre changement de thème, appelez-le à nouveau avec des SystemBarStyle correspondants lors du changement de thème. Sous la navigation à trois boutons, Android ajoute un voile translucide ; conservez-le sauf si la barre inférieure fournit déjà un fond solide.

Bannières publicitaires

Une bannière en bas se place dans l'emplacement bottomBar du scaffold, au-dessus de l'inset de la barre de navigation, avec sa hauteur réservée pour que le contenu ne saute pas. Ne laissez jamais une bannière se trouver sous la barre de gestes ou chevaucher les contrôles de navigation ; c'est à la fois un bug de mise en page et un problème de politique publicitaire.

Checklist pour chaque écran

  • L'arrière-plan atteint les bords physiques supérieur et inférieur.
  • Aucun texte ou contrôle sous la barre d'état, la découpe, la barre de navigation ou l'indicateur d'accueil.
  • Le dernier élément de la liste peut défiler complètement au-dessus de la barre inférieure.
  • Les champs de texte focalisés restent visibles avec le clavier ouvert.
  • L'affichage est correct en paysage (découpe sur le côté) et en thème sombre.
  • Les insets sont appliqués une seule fois, sans doublon.

Si la compétence edge-to-edge de Google est installée, utilisez-la pour le dépannage spécifique à Android au-delà de ce guide.

Skills associés