Explique a franja no Android P. O que fazer com o Android Cutout?

Queimado em setembro de 2007. Em setembro de 2017, a Apple voltou a moda, introduzindo o iPhone X. Não é de surpreender que nossos amigos da China, sem pensar duas vezes, tenham copiado esse design da Apple (embora a primeira mini-franja ainda estivesse no Essential Phone, que não decolou). Mas o que vemos agora? Huawei P20, Asus Zenfone 5, OnePlus 6, Motorola One Power, Xiaomi Redmi 6 e outros fabricantes mais ou menos conhecidos já produzem ou anunciam telefones com franja. Samsung e Google foram as últimas fortalezas nesta corrida pela luta pelo hype pela falta de moldura. Ou não? Segundo rumores, o Google Pixel 3 XL também estará com essa porcaria com um decote gracioso. Bem, nós, como desenvolvedores, só podemos otimizar seus aplicativos para esse recorte para que os usuários possam continuar a usá-los confortavelmente. Peço detalhes sob gato.



Primeiro, precisamos descobrir se o aplicativo precisa de alguma otimização?
Se você tiver um aplicativo de tela cheia ou o windowActionBarOverlay = true presente no tema, provavelmente será necessário.

Quase todos os aplicativos estão longe de uma única tela, e você pode não perceber como o layout será executado em um deles. Especialmente se o aplicativo tiver um código legado volumoso. Portanto, você ainda deve percorrer todas as telas principais e verificar novamente. Vamos descobrir o que precisa ser feito para isso.

1. Prepare um dispositivo / emulador de teste


Para testar seu aplicativo com franja, você precisa (obrigado, cap!) Android P. Atualmente, o Android P Preview 5 está disponível para os seguintes dispositivos (graças ao Project Treble):
Telefone Essencial
Google Pixel 2;
Google Pixel 2 XL;
Google Pixel
Google Pixel XL
Nokia 7 plus;
OnePlus 6;
Oppo R15 Pro;
Sony Xperia XZ2;
Vivo X21UD;
Vivo X21;
Xiaomi Mi Mix 2S

Para instalar o Android P no seu dispositivo, basta ir aqui e clicar em "Get Beta" para o seu dispositivo. Obtendo-o pelo ar ou rolando você mesmo - a escolha é sua. As instruções no site estão anexadas.
Mas se você não pode ou não deseja instalar o Android P no dispositivo, ninguém cancelou o emulador. Instruções de instalação aqui .

2. Ligue o estrondo por meio de programação (se não houver hardware)


Tudo é simples aqui: vá para Sistema -> Opções do desenvolvedor -> Simular uma exibição com um recorte.
Existem 3 opções para escolher:
  • Corner
  • Duplo
  • Alto


Eles têm a seguinte aparência:
CornerDuploAlto

3. Percorra as telas principais


Obviamente, este caso será diferente para todos. Alguém tem lógica simples, alguém não. Vou dar alguns exemplos de telas com layout percorrido que encontrei em nosso aplicativo.
ExplorarPerfil

Agora vamos ver quais são as maneiras de eliminar falhas de layout.

Sem aumentar o compileSdkVersion

Começando com a API 20, a classe WindowInsets apareceu, que é um objeto Rect que descreve as partes acessíveis e inacessíveis da tela. Juntamente com eles, esses métodos apareceram no modo de exibição que podemos usar para processar as coordenadas de partes inacessíveis da tela:

 WindowInsets dispatchApplyWindowInsets(WindowInsets); WindowInsets onApplyWindowInsets(WindowInsets); void requestApplyInsets(); void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener); 

Detalhes sobre como usá-los estão aqui .

Existem duas maneiras de usar esses métodos:
a) coloque a tag android:fitsSystemWindows="true" no layout do seu layout ou visualização;
b) faça isso a partir do código:

 layout.setFitsSystemWindows(true); layout.requestApplyInsets(); 

WasTornou-se

Atualize o compileSdkVersion para a versão 28

Em um futuro próximo, você terá que mudar para esta versão. Por que não se preparar para isso agora? Mas tenha cuidado se você tiver testes de unidade em seu projeto (e espero que você os tenha), o pacote JUnit foi movido. Como conectá-lo é descrito aqui .

Então, quais opções o Android P agora nos fornece?

A. WindowManager.LayoutParams possui 3 novos sinalizadores:

Como se inscrever?

 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 

B. Se a opção A não é adequada para você e você precisa levar em consideração a localização do recorte incorreto (por exemplo, algo é exibido diretamente na barra de status, como uma mensagem de conexão no Telegram), nesse caso, a nova classe DisplayCutout ajudará.
Considere seus métodos:

Com eles, você já pode fazer tudo o que é suficiente para a imaginação. Você quer - mova a margin no código neles. OnApplyWindowInsetsListener desejar, trate-o em OnApplyWindowInsetsListener e consumeDisplayCutout() . Talvez você precise de manipulações mais complexas. Vou dar um exemplo simples de como denotar um estrondo.

 class SampleFragment() : Fragment() { private lateinit var root: ViewGroup override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.sample_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) root = view.findViewById(R.id.root) addArrowsToCutout() } private fun addArrowsToCutout() { // ,      attach  window,    null' val cutoutList = root.rootWindowInsets?.displayCutout?.boundingRects cutoutList?.forEach { addArrow(context!!.getDrawable(R.drawable.left), it.left.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateLeftArrow) addArrow(context!!.getDrawable(R.drawable.right), it.right.toFloat(), it.top + (it.bottom - it.top).toFloat() / 2, ::calculateRightArrow) addArrow(context!!.getDrawable(R.drawable.top), it.left + (it.right - it.left).toFloat() / 2, it.top.toFloat(), ::calculateTopArrow) addArrow(context!!.getDrawable(R.drawable.bottom), it.left + (it.right - it.left).toFloat() / 2, it.bottom.toFloat(), ::calculateBottomArrow) } } private fun addArrow(arrowIcon: Drawable, x: Float, y: Float, calculation: (View, Float, Float) -> Unit) { val arrowView = ImageView(context) arrowView.setImageDrawable(arrowIcon) arrowView.layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) root.addView(arrowView) arrowView.post { calculation(arrowView, x, y) } } private fun calculateLeftArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width arrowView.y = y - arrowView.height / 2 } private fun calculateRightArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x arrowView.y = y - arrowView.height / 2 } private fun calculateTopArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y - arrowView.height } private fun calculateBottomArrow(arrowView: View, x: Float, y: Float) { arrowView.x = x - arrowView.width / 2 arrowView.y = y } } 

Retrato


CornerDuploAlto


Paisagem


Corner
Duplo
Alto

Então, como vemos, a margem nos trará alguns inconvenientes e nos fará gestos extras / manipulações adicionais. Em princípio, tudo está resolvido. O principal é começar a eliminar as deficiências de layout o mais rápido possível, a fim de ter tempo suficiente para a preparação. Lide com suas edições com sucesso. Que o Google não quebre seu jogo!

Source: https://habr.com/ru/post/pt419109/


All Articles