Para permitir que seu app tenha controle total sobre onde o conteúdo é renderizado, siga estas etapas de configuração. Sem essas etapas, o app pode renderizar cores pretas ou sólidas atrás da interface do sistema ou não animar de forma síncrona com o teclado virtual.
- Segmente o Android 15 (nível 35 da API) ou versões mais recentes para aplicar o modo de ponta a ponta no Android 15 e versões mais recentes. O app aparece atrás da interface do sistema. Você pode ajustar a interface do app processando encartes.
- Se quiser, chame
enableEdgeToEdge()
emActivity.onCreate()
, o que permite que o app seja de ponta a ponta em versões anteriores do Android. Defina
android:windowSoftInputMode="adjustResize"
na entradaAndroidManifest.xml
da sua atividade. Essa configuração permite que seu app receba o tamanho do IME de software como encartes, o que ajuda a aplicar o layout e o padding adequados quando o IME aparece e desaparece no app.<!-- 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">
Usar APIs do Compose
Depois que sua atividade assumir o controle do processamento de todos os encartes, use as APIs do Compose para garantir que o conteúdo não fique oculto e que os elementos interativos não se sobreponham à interface do sistema. Essas APIs também sincronizam o layout do app com mudanças de encarte.
Por exemplo, este é o método mais básico de aplicar encartes ao conteúdo de todo o app:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
Esse snippet aplica os encartes de janela safeDrawing
como padding em todo o conteúdo do app. Isso garante que os elementos interativos não se sobreponham à interface do sistema, mas também significa que nada do app será renderizado atrás da interface do sistema para alcançar um efeito de ponta a ponta. Para aproveitar ao máximo toda a janela, é necessário ajustar onde os encartes são aplicados em uma tela por tela ou componente por componente.
Todos esses tipos de encarte são animados automaticamente com animações de IME portadas para a API 21. Por extensão, todos os layouts que usam esses encartes também são animados automaticamente à medida que os valores mudam.
Há duas maneiras principais de usar esses tipos de encartes para ajustar os layouts combináveis: modificadores de padding e de tamanho de encarte.
Modificadores de padding
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
aplica os encartes de janela especificados como padding, agindo da mesma forma que Modifier.padding
.
Por exemplo, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
aplica
os encartes de desenho seguros como padding em todos os quatro lados.
Há também vários métodos utilitários integrados para os tipos de encartes mais comuns.
Modifier.safeDrawingPadding()
é um desses métodos, equivalente a
Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
. Há modificadores análogos para os outros tipos de encartes.
Modificadores de tamanho de encarte
Os modificadores a seguir aplicam uma quantidade de encartes de janela definindo o tamanho do componente como o tamanho dos encartes:
Aplica o lado inicial de windowInsets como a largura (como |
|
Aplica o lado final de windowInsets como a largura (como |
|
Aplica o lado de cima de windowInsets como a altura (como |
|
|
Aplica a parte de baixo de windowInsets como a altura (como |
Esses modificadores são especialmente úteis para dimensionar um Spacer
que ocupa o espaço dos encartes:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consumo de encartes
Os modificadores de padding de encarte (windowInsetsPadding
e helpers como
safeDrawingPadding
) consomem automaticamente a parte dos encartes que são
aplicados como padding. Ao se aprofundar na árvore de composição, os modificadores de padding de encarte aninhados e os modificadores de tamanho de encarte sabem que uma parte dos encartes já foi consumida por modificadores de padding de encarte externos e evitam usar a mesma parte dos encartes mais de uma vez, o que resultaria em muito espaço extra.
Os modificadores de tamanho de encarte também evitam usar a mesma parte dos encartes mais de uma vez se eles já tiverem sido consumidos. No entanto, como eles estão mudando o tamanho diretamente, não consomem encartes.
Como resultado, o aninhamento de modificadores de padding muda automaticamente a quantidade de padding aplicada a cada elemento combinável.
Analisando o mesmo exemplo de LazyColumn
de antes, o LazyColumn
está sendo
redimensionado pelo modificador imePadding
. Dentro do LazyColumn
, o último item tem
o tamanho da altura da parte de baixo das barras de sistema:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Quando o IME está fechado, o modificador imePadding()
não aplica padding, já que
o IME não tem altura. Como o modificador imePadding()
não está aplicando padding,
nenhum encarte está sendo consumido, e a altura do Spacer
será o tamanho
da parte de baixo das barras de sistema.
Quando o IME é aberto, os encartes do IME são animados para corresponder ao tamanho dele, e o modificador
imePadding()
começa a aplicar padding na parte de baixo para redimensionar o
LazyColumn
à medida que o IME é aberto. À medida que o modificador imePadding()
começa a aplicar
padding na parte de baixo, ele também começa a consumir essa quantidade de encartes. Portanto, a altura do Spacer
começa a diminuir, já que parte do espaçamento para as barras de sistema já foi aplicada pelo modificador imePadding()
. Quando o
modificador imePadding()
aplica um padding da parte de baixo maior
que as barras de sistema, a altura do Spacer
é zero.
Quando o IME é fechado, as mudanças acontecem ao contrário: o Spacer
começa a
expandir de uma altura zero quando o imePadding()
está aplicando menos que a
parte de baixo das barras de sistema, até que o Spacer
corresponda à altura da
parte de baixo das barras de sistema quando o IME estiver completamente animado.
TextField
.Esse comportamento é realizado por meio da comunicação entre todos os modificadores
windowInsetsPadding
e pode ser influenciado de algumas outras
maneiras.
O Modifier.consumeWindowInsets(insets: WindowInsets)
também consome encartes
da mesma forma que o Modifier.windowInsetsPadding
, mas não aplica
os encartes consumidos como padding. Isso é útil em combinação com os modificadores de tamanho de encarte, para indicar aos irmãos que uma determinada quantidade de encartes já foi consumida:
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 comporta de maneira
muito semelhante à versão com um argumento WindowInsets
, mas usa um
PaddingValues
arbitrário para consumir. Isso é útil para informar
às crianças quando o padding ou o espaçamento são fornecidos por algum outro mecanismo que não os
modificadores de padding de encarte, como um Modifier.padding
comum ou espaçadores de
altura fixa:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
Nos casos em que os encartes de janela brutos são necessários sem consumo, use os valores WindowInsets
diretamente ou use WindowInsets.asPaddingValues()
para retornar um PaddingValues
dos encartes que não são afetados pelo consumo.
No entanto, devido às seguintes ressalvas, prefira usar os modificadores de preenchimento de encartes de janela
e os modificadores de tamanho de encartes de janela sempre que possível.
Encaixes e fases do Jetpack Compose
O Compose usa as APIs principais do AndroidX para atualizar e animar encartes, que usam as APIs da plataforma subjacente para gerenciar encartes. Devido a esse comportamento da plataforma, os encartes têm uma relação especial com as fases do Jetpack Compose.
Os valores de encartes são atualizados após a fase de composição, mas antes da fase de layout. Isso significa que a leitura do valor de encartes na composição geralmente usa um valor dos encartes que está um frame atrasado. Os modificadores integrados descritos nesta página foram criados para atrasar o uso dos valores dos encartes até a fase de layout, o que garante que os valores de encarte sejam usados no mesmo frame em que são atualizados.