Edge-to-edge no Compose Multiplatform
O Android exige edge-to-edge para aplicativos que visam SDK 35 ou superior, e a opção de desativar desaparece no SDK 36. Aplicativos iOS devem desenhar sob a barra de status e o indicador de início (home indicator). Construa cada tela edge-to-edge desde o início.
A regra: backgrounds desenham atrás das barras do sistema; conteúdo e controles são preenchidos com insets.
Ativação
Android (MainActivity em androidApp), antes de setContent:
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent { App() }
}
No manifesto, defina android:windowSoftInputMode="adjustResize" na Activity para que as insets do IME cheguem ao Compose.
iOS (ContentView.swift): deixe o Compose dono de toda a tela, caso contrário o SwiftUI aplica as áreas seguras primeiro e o Compose vê insets zero.
ComposeView().ignoresSafeArea()
O Scaffold faz a maior parte do trabalho
Scaffold(
topBar = { TopAppBar(title = { Text(title) }) }, // preenche a si mesmo para a barra de status
bottomBar = { NavigationBar { /* ... */ } }, // preenche a si mesmo para a barra de navegação
) { innerPadding ->
LazyColumn(
contentPadding = innerPadding, // conteúdo rola sob as barras
modifier = Modifier.fillMaxSize(),
) { /* items */ }
}
- Sempre use
innerPadding. Para listas, passe-o comocontentPaddingpara que os itens rolem atrás de barras translúcidas; para conteúdo não rolável, useModifier.padding(innerPadding). - Barras do Material 3 consomem suas próprias insets. Não adicione
statusBarsPadding()sobre umTopAppBar. - Scaffolds aninhados dobram o padding. Dê ao scaffold interno
contentWindowInsets = WindowInsets(0)ou apliqueconsumeWindowInsets(innerPadding)no conteúdo externo.
Telas sem Scaffold
Box(Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background)) { // background preenche a tela
Column(Modifier.fillMaxSize().windowInsetsPadding(WindowInsets.safeDrawing)) { /* conteúdo */ }
}
WindowInsets.safeDrawing cobre barra de status, barra de navegação, recorte da tela e teclado. Use safeContent quando gestos forem importantes. Aplique o padding de insets uma vez, no nível que é dono do conteúdo, nunca no pai e no filho.
Teclado
- Telas com entrada:
Modifier.imePadding()no container rolável, ousafeDrawingque já inclui o IME. - Um botão inferior que deve ficar acima do teclado: coloque-o no slot
bottomBardo Scaffold comModifier.imePadding(), ou useWindowInsets.ime.union(WindowInsets.navigationBars). - Torne o conteúdo rolável para que um campo focado possa aparecer.
Conteúdo sangrado (full-bleed)
Imagens, mapas, vídeos e prévias de câmera devem ignorar as insets e preencher a tela. Sobrepomos controles e aplicamos padding apenas neles com WindowInsets.safeDrawing.
Contraste dos ícones da barra de sistema
As barras são transparentes, então o contraste dos ícones é sua responsabilidade. No Android, enableEdgeToEdge() escolhe ícones claros ou escuros baseados no tema do sistema; se o app tiver seu próprio interruptor de tema, chame-o novamente com SystemBarStyle correspondentes quando o tema mudar. Com navegação de três botões, o Android adiciona um scrim translúcido; mantenha-o a menos que a barra inferior já forneça um fundo sólido.
Banners de anúncios
Um banner inferior deve ficar dentro do slot bottomBar do Scaffold, acima da inset da barra de navegação, com sua altura reservada para que o conteúdo não pule. Nunca deixe um banner sob a barra de gestos ou sobrepor controles de navegação; isso é tanto um bug de layout quanto um problema de política de anúncios.
Checklist para cada tela
- O background alcança as bordas física superior e inferior.
- Nenhum texto ou controle sob a barra de status, recorte, barra de navegação ou indicador de início.
- O último item da lista pode rolar completamente acima da barra inferior.
- Campos de texto focados permanecem visíveis com o teclado aberto.
- Parece correto em paisagem (recorte na lateral) e no tema escuro.
- As insets são aplicadas uma vez, não duplicadas.
Se o skill edge-to-edge do Google estiver instalado, use-o para solução de problemas específicos do Android além deste.