Um corte da tela é uma área em alguns dispositivos que se estende até a superfície da tela. Ele permite uma experiência de ponta a ponta, além de fornecer espaço para sensores importantes na parte frontal do dispositivo.
O Android oferece suporte a cortes de tela em dispositivos com o Android 9 (nível 28 da API) e versões mais recentes. No entanto, os fabricantes de dispositivos também podem oferecer suporte a cortes da tela em dispositivos com o Android 8.1 ou versões anteriores.
Este documento descreve como implementar suporte para dispositivos com cortes, incluindo como trabalhar com a área de corte, ou seja, o retângulo de ponta a ponta na superfície da tela que contém o corte.
![Uma imagem mostrando um exemplo de corte da tela na parte superior central](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-intro.png?authuser=5&hl=pt)
Escolher como o app processa áreas de corte
Se você não quiser que seu conteúdo se sobreponha a uma área de corte, geralmente basta
garantir que ele não se sobreponha à barra de status e à
barra de navegação. Se você estiver renderizando na área de corte, use
WindowInsetsCompat.getDisplayCutout()
para extrair um objeto DisplayCutout
que contenha os encartes seguros e a caixa delimitadora para cada corte. Essas APIs permitem
verificar se o conteúdo se sobrepõe ao corte para que você possa
reposicionar, se necessário.
Você também pode determinar se o conteúdo está disposto atrás da área de corte. O
atributo de layout da janela
layoutInDisplayCutoutMode
controla como o conteúdo é renderizado na área de corte.
É possível definir layoutInDisplayCutoutMode
como um dos seguintes valores:
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
: o conteúdo é renderizado na área de corte quando o corte da tela está contido em uma barra do sistema. Caso contrário, a janela não se sobrepõe ao corte da tela. Por exemplo, o conteúdo pode ficar com efeito letterbox quando exibido no modo paisagem. Se o app for destinado ao SDK 35, isso será interpretado comoALWAYS
para janelas não flutuantes.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
: o conteúdo sempre pode se estender até as áreas de corte. Caso o app seja destinado ao SDK 35 e esteja sendo executado em um dispositivo Android 15, esse é o único modo permitido para janelas não flutuantes para garantir uma exibição de ponta a ponta.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
: o conteúdo é renderizado na área de corte nos modos retrato e paisagem. Não use para janelas flutuantes. Se o app for direcionado ao SDK 35, isso será interpretado comoALWAYS
para janelas não flutuantes.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
: o conteúdo nunca é renderizado na área de corte. Se o app for direcionado ao SDK 35, isso será interpretado comoALWAYS
para janelas não flutuantes.
Você pode definir o modo de corte de forma programática ou definindo um
estilo na sua atividade. O exemplo
abaixo define um estilo para aplicar o atributo LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
à atividade.
<style name="ActivityTheme"> <item name="android:windowLayoutInDisplayCutoutMode"> shortEdges <!-- default, shortEdges, or never --> </item> </style>
As seções a seguir descrevem os diferentes modos de corte com mais detalhes.
Comportamento padrão
Se o app for direcionado ao SDK 35 e estiver em execução em um dispositivo Android 15,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
será o comportamento padrão, e
LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
será interpretado como
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
para janelas não flutuantes.
Caso contrário, LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT
será o padrão.
Renderizar conteúdo em áreas de corte de borda curta
Caso o app seja destinado ao SDK 35 e esteja em execução em um dispositivo Android 15,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
será interpretado como
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
para janelas não flutuantes.
Com LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
, o
conteúdo se estende até a área de corte na borda curta da tela no
retrato e no modo paisagem, independente de as barras do sistema estarem ocultas ou
visíveis. Ao usar esse modo, verifique se nenhum conteúdo importante se sobrepõe à
área de corte.
A imagem abaixo é um exemplo de LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
para um dispositivo no modo retrato:
![Uma imagem que mostra o conteúdo sendo renderizado na área de corte no modo retrato](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-1.png?authuser=5&hl=pt)
A imagem abaixo é um exemplo de LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
para um dispositivo no modo paisagem:
![Uma imagem que mostra o conteúdo sendo renderizado na área de corte no modo paisagem](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-short-edges-2.png?authuser=5&hl=pt)
Nesse modo, a janela se estende por baixo dos cortes na borda curta da tela nos modos retrato e paisagem, independente de a janela estar ocultando as barras do sistema.
Considera-se que há um corte no canto da borda curta:
![Uma imagem mostrando um dispositivo com um corte de canto](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-corner.png?authuser=5&hl=pt)
Nunca renderize conteúdo na área de corte da tela
Caso o app seja destinado ao SDK 35 e esteja em execução em um dispositivo Android 15,
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
será interpretado como
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
para janelas não flutuantes.
Com LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
, a janela nunca pode se sobrepor à área de corte.
Veja a seguir um exemplo de LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
no
retrato:
![Uma imagem mostrando o LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER no modo retrato](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-never.png?authuser=5&hl=pt)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
para o modo retrato.
Veja a seguir um exemplo de LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
no
modo paisagem:
![Uma imagem mostrando o LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER para o modo paisagem](https://developer.android.com/static/develop/ui/views/layout/display-cutout/images/cutout-never-landscape.png?authuser=5&hl=pt)
LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
no modo paisagem.
Práticas recomendadas para a compatibilidade com corte de tela
Ao trabalhar com cortes da tela, considere o seguinte:
- Esteja atento ao posicionamento dos elementos essenciais da IU. Não deixe a área de corte ocultar textos, controles ou outras informações importantes.
- Não coloque nem estenda elementos interativos que exigem reconhecimento por toque na área de corte. A sensibilidade ao toque pode ser menor na área de corte.
Sempre que possível, use
WindowInsetsCompat
para extrair a altura da barra de status e determinar o padding adequado a ser aplicado ao conteúdo. Evite fixar a altura da barra de status no código, porque isso pode resultar em conteúdo sobreposto ou cortado.Figura 7. Use WindowInsetsCompat
para evitar sobrepor ou cortar o conteúdo.Use
View.getLocationInWindow()
para determinar quanto espaço da janela o app está usando. Não presuma que o app esteja usando a janela inteira e não useView.getLocationOnScreen()
.Use os modos de corte
always
,shortEdges
ounever
se o app precisar entrar e sair do modo imersivo. O comportamento de corte padrão pode fazer com que o conteúdo no app seja renderizado na área de corte enquanto as barras de sistema estão presentes, mas não no modo imersivo. Isso faz com que o conteúdo se mova para cima e para baixo durante as transições, conforme demonstrado no exemplo a seguir.Figura 8. Exemplo de conteúdo que se move para cima e para baixo durante as transições. No modo imersivo, tenha cuidado ao usar as coordenadas de janela e tela, já que o app não usa a tela inteira quando está com efeito letterbox. Por causa do efeito letterbox, as coordenadas da origem da tela não são as mesmas que as coordenadas da origem da janela. Você pode transformar as coordenadas da tela nas coordenadas da visualização conforme necessário usando
getLocationOnScreen()
. A imagem a seguir mostra como as coordenadas diferem quando o conteúdo tem efeito letterbox:Figura 9. Coordenadas de janela versus tela quando o conteúdo tem efeito letterbox. Ao processar
MotionEvent
, useMotionEvent.getX()
eMotionEvent.getY()
para evitar problemas de coordenadas semelhantes. Não useMotionEvent.getRawX()
ouMotionEvent.getRawY()
.
Testar como seu conteúdo é renderizado
Teste todas as telas e experiências do seu app. Teste em dispositivos com diferentes tipos de corte, se possível. Caso você não tenha um dispositivo com corte, pode simular configurações comuns de corte em qualquer dispositivo ou emulador com o Android 9 ou versões mais recentes fazendo o seguinte:
- Ative as Opções do desenvolvedor.
- Na tela Opções do desenvolvedor, role para baixo até a seção Desenho e selecione Simular uma tela com corte.
Selecione o tipo de corte.
Figura 10. Opções do desenvolvedor para testar como o conteúdo é renderizado.
Outros recursos
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES (em inglês)
- LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT