Depois que a atividade assumir o controle do processamento de todos os insets, você poderá usar as APIs do Compose para garantir que o conteúdo não seja obscurecido e que os elementos interativos não se sobreponham à interface do sistema. Essas APIs também sincronizam o layout do app com as mudanças de engaste.
Por exemplo, este é o método mais básico de aplicar os insets 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. Embora isso garanta que os elementos interativos não
se sobreponham à interface do sistema, também significa que nenhum elemento do app será exibido atrás
da interface do sistema para alcançar um efeito de borda a borda. Para aproveitar toda a
janela, você precisa ajustar onde os insets são aplicados em cada tela
ou componente.
Todos esses tipos de inseto são animados automaticamente com animações de IME reportadas para a API 21. Por extensão, todos os layouts que usam esses insets também são animados automaticamente conforme os valores de inset mudam.
Há duas maneiras principais de usar esses tipos de inseto para ajustar os layouts do elemento combinável: modificadores de padding e modificadores de tamanho de inseto.
Modificadores de padding
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
aplica os
insets de janela fornecidos como padding, agindo exatamente como Modifier.padding
.
Por exemplo, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
aplica
os engastes de desenho seguros como padding nos quatro lados.
Há também vários métodos utilitários integrados para os tipos de inset mais comuns.
Modifier.safeDrawingPadding()
é um desses métodos, equivalente a
Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
. Há modificadores
análogos para os outros tipos de inset.
Modificadores de tamanho de inserção
Os modificadores a seguir aplicam uma quantidade de engastes de janela definindo o tamanho do componente como o tamanho dos engastes:
Aplica o lado inicial de windowInsets como a largura (como |
|
Aplica o lado final de windowInsets como a largura (como |
|
Aplica a parte de cima de windowInsets como a altura (como |
|
|
Aplica a parte inferior de windowInsets como a altura (como |
Esses modificadores são especialmente úteis para dimensionar um Spacer
que ocupa o
espaço de insets:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
Consumo de Inset
Os modificadores de padding de inserção (windowInsetsPadding
e auxiliares como
safeDrawingPadding
) consomem automaticamente a parte dos insets que são
aplicadas como padding. Ao se aprofundar na árvore de composição, os modificadores de padding
anexados e os modificadores de tamanho de anexos aninhados sabem que parte dos
anexados já foi consumida por modificadores de padding externo e evitam
usar a mesma parte dos anexos mais de uma vez, o que resultaria em muito
espaço extra.
Os modificadores de tamanho de inseto também evitam usar a mesma parte de insetos mais de uma vez se os insetos já foram consumidos. No entanto, como elas mudam de tamanho diretamente, elas não consomem insets.
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
anterior, o LazyColumn
está sendo
redimensionado pelo modificador imePadding
. Dentro do LazyColumn
, o último item é
dimensionado para ser a altura da parte de baixo das barras do 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 inseto está sendo consumido, e a altura da Spacer
será o tamanho da
parte de baixo das barras do sistema.
Quando o IME é aberto, os insets são animados para corresponder ao tamanho do IME, e o
modificador imePadding()
começa a aplicar o padding inferior para redimensionar o
LazyColumn
conforme o IME é aberto. À medida que o modificador imePadding()
começa a aplicar
o padding inferior, ele também começa a consumir essa quantidade de insets. Portanto, a
altura do Spacer
começa a diminuir, já que parte do espaçamento das barras
do sistema já foi aplicado pelo modificador imePadding()
. Quando o
modificador imePadding()
aplica um valor de padding inferior maior
que as barras do sistema, a altura do Spacer
é zero.
Quando o IME é fechado, as mudanças acontecem de forma inversa: o Spacer
começa a
se expandir a partir de uma altura de zero quando o imePadding()
está aplicando menos que a
parte de baixo das barras do sistema, até que o Spacer
corresponda à altura da
parte de baixo das barras do sistema quando o IME é completamente animado.
TextField
.Esse comportamento é alcançado pela comunicação entre todos os
modificadores windowInsetsPadding
e pode ser influenciado de algumas outras
maneiras.
Modifier.consumeWindowInsets(insets: WindowInsets)
também consome encartes
da mesma forma que Modifier.windowInsetsPadding
, mas não aplica
os encartes consumidos como padding. Isso é útil em combinação com os modificadores de tamanho
de insetos, para indicar aos irmãos que uma certa quantidade de insetos
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)) }
O Modifier.consumeWindowInsets(paddingValues: PaddingValues)
se comporta de maneira muito
semelhante à versão com um argumento WindowInsets
, mas consome um
PaddingValues
arbitrário. Isso é útil para informar
elementos filhos quando o padding ou o espaçamento é fornecido por algum outro mecanismo que não seja os
modificadores de padding de inserção, 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 insets de janela brutos são necessários sem consumo, use os
valores de WindowInsets
diretamente ou use WindowInsets.asPaddingValues()
para
retornar um PaddingValues
dos insetos que não são afetados pelo consumo.
No entanto, devido às ressalvas abaixo, prefira usar os modificadores de preenchimento
e de tamanho de encartes de janela sempre que possível.
Insets e fases do Jetpack Compose
O Compose usa as APIs principais do AndroidX para atualizar e animar insets, que usam as APIs da plataforma para gerenciar insets. Devido a esse comportamento da plataforma, os insets têm uma relação especial com as fases do Jetpack Compose.
O valor dos insets é atualizado após a fase de composição, mas antes da fase de layout. Isso significa que ler o valor dos encartes na composição geralmente usa um valor dos encartes que está atrasado em um frame. Os modificadores integrados descritos nesta página são criados para atrasar o uso dos valores das informações até a fase de layout, o que garante que os valores sejam usados no mesmo frame em que são atualizados.