Depois de segmentar o SDK 35 ou mais recente em um dispositivo com o Android 15 ou mais recente, o app será mostrado de ponta a ponta. A janela abrange toda a largura e altura da tela, sendo renderizada atrás das barras do sistema. As barras do sistema incluem a barra de status, a barra de legenda e a barra de navegação.
Muitos apps têm uma barra de apps superior. A barra de apps superior deve se estender até a borda superior da tela e ser exibida atrás da barra de status. Opcionalmente, a barra de apps superior pode diminuir até a altura da barra de status quando o conteúdo é rolado.
Muitos apps também têm uma barra de apps inferior ou uma barra de navegação inferior. Essas barras também precisam se estender até a borda inferior da tela e ser mostradas atrás da barra de navegação. Caso contrário, os apps precisam mostrar o conteúdo rolável atrás da barra de navegação.
Ao implementar um layout de ponta a ponta no seu app, lembre-se do seguinte:
- Ativar uma tela de ponta a ponta
- Implementar layouts adaptáveis para otimizar a experiência do usuário em diferentes formatos
- Processar sobreposições visuais
- Considerar mostrar scrims atrás das barras do sistema
Ativar a tela de ponta a ponta
Se o app for destinado ao SDK 35 ou mais recente, o modo de ponta a ponta será ativado automaticamente para dispositivos com o Android 15 ou mais recente.
Para ativar o modo de ponta a ponta em versões anteriores do Android, chame
enableEdgeToEdge manualmente em onCreate da sua Activity.
Kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.enableEdgeToEdge(window)
...
}
Java
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WindowCompat.enableEdgeToEdge(getWindow());
...
}
Por padrão, enableEdgeToEdge() torna as barras do sistema transparentes, exceto no modo de navegação com três botões, em que a barra de navegação recebe um scrim translúcido. As cores dos ícones do sistema e do scrim são ajustadas com base no tema claro ou escuro do sistema.
Para ativar a tela de ponta a ponta no app sem usar a
enableEdgeToEdge() função, consulte
Configurar manualmente a tela de ponta a ponta.
Processar sobreposições usando encartes
Algumas visualizações do app podem ser renderizadas atrás das barras do sistema, conforme mostrado na Figura 3.
É possível resolver sobreposições reagindo a insets, que especificam quais partes da tela se cruzam com a interface do sistema, como a barra de navegação ou a barra de status. Usar essas partes da interface pode possibilitar mostrar mais conteúdo, mas também pode informar seu app sobre gestos do sistema.
Os tipos de encartes que se aplicam à exibição do app de ponta a ponta são:
Encartes de barras do sistema:ideais para visualizações que podem ser tocadas e que não podem ser obscurecidas visualmente pelas barras do sistema.
Encartes de corte da tela:para áreas em que pode haver um corte da tela devido ao formato do dispositivo.
Encartes de gestos do sistema:para áreas de navegação por gestos usadas pelo sistema que têm prioridade sobre o app.
Encartes de barras do sistema
Os recuos da barra de sistema são o tipo mais usados com frequência. Eles representam a área em que a interface do sistema é mostrada no eixo Z acima do app. Eles são mais adequados para mover ou preencher visualizações no app que podem ser tocadas e que não podem ser obscurecidas visualmente pelas barras do sistema.
Por exemplo, o botão de ação flutuante (FAB, na sigla em inglês) na Figura 3 está parcialmente obscurecido pela barra de navegação:
Para evitar esse tipo de sobreposição visual no modo de gesto ou de botão, é possível aumentar as margens da visualização usando
getInsets(int)
com
WindowInsetsCompat.Type.systemBars().
O exemplo de código a seguir mostra como implementar encartes de barra de sistema:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(fab) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) // Apply the insets as a margin to the view. This solution sets // only the bottom, left, and right dimensions, but you can apply whichever // insets are appropriate to your layout. You can also update the view padding // if that's more appropriate. v.updateLayoutParams<MarginLayoutParams> { leftMargin = insets.left bottomMargin = insets.bottom rightMargin = insets.right } // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(fab, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); // Apply the insets as a margin to the view. This solution sets only the // bottom, left, and right dimensions, but you can apply whichever insets are // appropriate to your layout. You can also update the view padding if that's // more appropriate. MarginLayoutParams mlp = (MarginLayoutParams) v.getLayoutParams(); mlp.leftMargin = insets.left; mlp.bottomMargin = insets.bottom; mlp.rightMargin = insets.right; v.setLayoutParams(mlp); // Return CONSUMED if you don't want the window insets to keep passing // down to descendant views. return WindowInsetsCompat.CONSUMED; });
Se você aplicar essa solução ao exemplo mostrado na Figura 3, não haverá sobreposição visual no modo de botão, conforme mostrado na Figura 4:
O mesmo se aplica ao modo de navegação por gestos, conforme mostrado na Figura 5:
Encartes de corte da tela
Alguns dispositivos têm cortes de tela. Normalmente, o corte fica na parte de cima da tela e é incluído na barra de status. Quando a tela do dispositivo está no modo paisagem, o corte pode estar na borda vertical. Dependendo do conteúdo que o app mostra na tela, é necessário implementar o padding para evitar cortes de tela, já que, por padrão, os apps são renderizados no corte da tela.
Por exemplo, muitas telas de apps mostram uma lista de itens. Não obscureça os itens da lista com o corte da tela ou as barras do sistema.
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(binding.recyclerView) { v, insets -> val bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() or WindowInsetsCompat.Type.displayCutout() ) v.updatePadding( left = bars.left, top = bars.top, right = bars.right, bottom = bars.bottom, ) WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(mBinding.recyclerView, (v, insets) -> { Insets bars = insets.getInsets( WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout() ); v.setPadding(bars.left, bars.top, bars.right, bars.bottom); return WindowInsetsCompat.CONSUMED; });
Determine o valor de WindowInsetsCompat usando o ou lógico das barras do sistema e os tipos de corte da tela.
Defina clipToPadding como RecyclerView para que o padding seja rolado com os itens da lista. Isso permite que os itens fiquem atrás das barras do sistema quando o usuário rola a tela, conforme mostrado no exemplo a seguir.
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
Encartes de gestos do sistema
Os encartes de gestos do sistema representam as áreas da janela em que os gestos do sistema têm prioridade sobre o app. Essas áreas são mostradas em laranja na Figura 6:
Assim como os insets da barra de sistema, é possível evitar a sobreposição dos insets de gestos do sistema
usando
getInsets(int)
com
WindowInsetsCompat.Type.systemGestures().
Use esses encartes para mover ou preencher visualizações deslizáveis para longe das bordas. Os casos de uso comuns incluem folhas de baixo,
deslizar em jogos e carrosséis implementados usando
ViewPager2.
No Android 10 ou mais recente, os encartes de gestos do sistema contêm um encarte inferior para o gesto inicial e um encarte esquerdo e direito para os gestos de voltar:
O exemplo de código a seguir mostra como implementar encartes de gestos do sistema:
Kotlin
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.updatePadding(insets.left, insets.top, insets.right, insets.bottom) // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. WindowInsetsCompat.CONSUMED }
Java
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) -> { Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()); // Apply the insets as padding to the view. Here, set all the dimensions // as appropriate to your layout. You can also update the view's margin if // more appropriate. view.setPadding(insets.left, insets.top, insets.right, insets.bottom); // Return CONSUMED if you don't want the window insets to keep passing down // to descendant views. return WindowInsetsCompat.CONSUMED; });
Componentes do Material Design
Muitos componentes do Material Design do Android baseados em visualizações
(com.google.android.material) processam encartes automaticamente, incluindo
BottomAppBar,
BottomNavigationView,
NavigationRailView
e NavigationView
No entanto, AppBarLayout
não processa encartes automaticamente. Adicione
android:fitsSystemWindows="true"
para processar encartes superiores.
Leia como processar encartes com componentes do Material Design no Compose.
Envio de encartes compatível com versões anteriores
Para interromper o envio de encartes para visualizações filhas e evitar o excesso de padding, é possível
consumir encartes usando a
WindowInsetsCompat.CONSUMED
constante. No entanto, em dispositivos com o Android 10 (nível 29 da API e versões anteriores), os recuos não são enviados para irmãos após chamar WindowInsetsCompat.CONSUMED, o que pode causar sobreposição visual não intencional.
Para confirmar que os encartes são enviados para irmãos em todas as versões compatíveis do Android, use ViewGroupCompat#installCompatInsetsDispatch antes de consumir
encartes, disponível no
AndroidX Core e Core-ktx 1.16.0-alpha01
e versões mais recentes.
Kotlin
// Use the i.d. assigned to your layout's root view, e.g. R.id.main val rootView = findViewById(R.id.main) // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView)
Java
// Use the i.d. assigned to your layout's root view, e.g. R.id.main LinearLayout rootView = findViewById(R.id.main); // Call before consuming insets ViewGroupCompat.installCompatInsetsDispatch(rootView);
Modo imersivo
Alguns conteúdos são melhores em tela cheia, oferecendo ao usuário uma experiência mais imersiva. É possível ocultar as barras do sistema para o modo imersivo usando
WindowInsetsController
e
WindowInsetsControllerCompat
bibliotecas:
Kotlin
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView) // Hide the system bars. windowInsetsController.hide(Type.systemBars()) // Show the system bars. windowInsetsController.show(Type.systemBars())
Java
Window window = getWindow(); WindowInsetsControllerCompat windowInsetsController = WindowCompat.getInsetsController(window, window.getDecorView()); if (windowInsetsController == null) { return; } // Hide the system bars. windowInsetsController.hide(WindowInsetsCompat.Type.systemBars()); // Show the system bars. windowInsetsController.show(WindowInsetsCompat.Type.systemBars());
Consulte Ocultar barras do sistema para o modo imersivo para mais informações sobre como implementar esse recurso.
Ícones da barra de sistema
Chamar enableEdgeToEdge garante que as cores dos ícones da barra do sistema sejam atualizadas quando o tema do dispositivo mudar.
Ao usar o modo de ponta a ponta, talvez seja necessário atualizar manualmente as cores dos ícones da barra de sistema para que eles contrastem com o plano de fundo do app. Por exemplo, para criar ícones de barra de status claros:
Kotlin
WindowCompat.getInsetsController(window, window.decorView) .isAppearanceLightStatusBars = false
Java
WindowCompat.getInsetsController(window, window.getDecorView()) .setAppearanceLightStatusBars(false);
Proteção da barra de sistema
Depois que o app for destinado ao SDK 35 ou mais recente, o modo de ponta a ponta será aplicado.
A barra de status do sistema e as barras de navegação por gestos são transparentes, mas a barra de navegação com três botões é translúcida. Chame enableEdgeToEdge para tornar isso compatível com versões anteriores.
No entanto, os padrões do sistema podem não funcionar para todos os casos de uso. Consulte as orientações de design das barras do sistema Android e o design de ponta a ponta para determinar se você quer usar barras do sistema transparentes ou translúcidas.
Criar barras do sistema transparentes
Crie uma barra de status transparente segmentando o Android 15 (SDK 35) ou mais recente ou chamando enableEdgeToEdge() com argumentos padrão para versões anteriores.
Crie uma barra de navegação por gestos transparente segmentando o Android 15 ou mais recente ou chamando enableEdgeToEdge() com argumentos padrão para versões anteriores. Para
a barra de navegação com três botões, defina Window.setNavigationBarContrastEnforced
como false. Caso contrário, um scrim translúcido será aplicado.
Criar barras do sistema translúcidas
Para criar uma barra de status translúcida, faça o seguinte:
- Atualize a dependência
androidx-corepara 1.16.0-beta01 ou mais recente. - Encapsule o layout XML em
androidx.core.view.insets.ProtectionLayoute atribua um ID. - Acesse programaticamente o
ProtectionLayoutpara definir proteções, especificando o lado e umGradientProtectionpara a barra de status.
<androidx.core.view.insets.ProtectionLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/list_protection" android:layout_width="match_parent" android:layout_height="match_parent"> <ScrollView android:id="@+id/item_list" android:clipToPadding="false" android:layout_width="match_parent" android:layout_height="match_parent"> <!--items--> </ScrollView> </androidx.core.view.insets.ProtectionLayout>
findViewById<ProtectionLayout>(R.id.list_protection) .setProtections( listOf( GradientProtection( WindowInsetsCompat.Side.TOP, // Ideally, this is the pane's background color paneBackgroundColor ) ) )
Verifique se o ColorInt transmitido para GradientProtection corresponde ao plano de fundo do conteúdo. Por exemplo, um layout de detalhes e listas mostrado em um dispositivo dobrável pode ter GradientProtections diferentes de cores diferentes para o painel de lista e o painel de detalhes.
Não crie uma barra de navegação por gestos translúcida. Para criar uma barra de navegação translúcida com três botões, faça uma das seguintes ações:
- Se o layout já estiver encapsulado em uma
ProtectionView, transmita umColorProtectionouGradientProtectionadicional para o métodosetProtections. Antes de fazer isso, verifique sewindow.isNavigationBarContrastEnforced = false. - Caso contrário, defina
window.isNavigationBarContrastEnforced = true.
Outras dicas
Outras dicas ao processar encartes.
Deixar o conteúdo rolável de ponta a ponta
Verifique se o último item da lista não está obscurecido pelas barras do sistema no RecyclerView ou NestedScrollView processando encartes e definindo clipToPadding como false.
O vídeo a seguir mostra um RecyclerView com a tela de ponta a ponta desativada (à esquerda) e ativada (à direita):
Consulte os snippets de código na seção Criar listas dinâmicas com o RecyclerView para ver um exemplo de código.
Abrir caixas de diálogo em tela cheia de ponta a ponta
Para abrir caixas de diálogo em tela cheia de ponta a ponta, chame enableEdgeToEdge na caixa de diálogo.
Kotlin
class MyAlertDialogFragment : DialogFragment() {
override fun onStart(){
super.onStart()
dialog?.window?.let { WindowCompat.enableEdgeToEdge(it) }
}
...
}
Java
public class MyAlertDialogFragment extends DialogFragment {
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
Window window = dialog.getWindow();
if (window != null) {
WindowCompat.enableEdgeToEdge(window);
}
}
}
...
}
Outros recursos
Consulte as referências a seguir para mais informações sobre o modo de ponta a ponta.
Blogs
- Dicas de processamento de encartes para a aplicação de ponta a ponta do Android 15 (link em inglês)
- WindowInsets: listeners para layouts (link em inglês)
Design
Outra documentação
Vídeos