Explica las explosiones en Android P. ¿Qué hacer con Android Cutout?

Quemado en septiembre de 2007. Era septiembre de 2017, Apple volvió la moda al margen, presentando el iPhone X. No es sorprendente que nuestros amigos de China, sin pensárselo dos veces, copiaran este diseño de Apple (aunque la primera mini-franja todavía estaba en el Essential Phone, que no despegó). ¿Pero qué vemos ahora? Huawei P20, Asus Zenfone 5, OnePlus 6, Motorola One Power, Xiaomi Redmi 6 y otros fabricantes más o menos conocidos ya producen o anuncian teléfonos con flequillo. Samsung y Google fueron los últimos bastiones en esta carrera por la lucha exagerada por la falta de marcos. O no? Según los rumores, el Google Pixel 3 XL también estará con esta basura con un elegante escote. Bueno, nosotros, como desarrolladores, solo podemos optimizar sus aplicaciones para este recorte para que los usuarios puedan seguir usándolas cómodamente. Pido detalles bajo cat.



Primero, ¿tenemos que averiguar si la aplicación necesita alguna optimización?
Si tiene una aplicación de pantalla completa o el elemento windowActionBarOverlay = true presente en el tema, lo más probable es que sea necesario.

Casi todas las aplicaciones están lejos de ser una sola pantalla, y es posible que no note cómo se verá el diseño en una de ellas. Especialmente si la aplicación tiene un voluminoso código heredado. Por lo tanto, aún debe pasar por todas las pantallas principales y verificar dos veces. Vamos a averiguar qué hay que hacer para esto.

1. Prepare un dispositivo de prueba / emulador


Para probar su aplicación con flequillo, necesita (gracias, cap!) Android P. Actualmente, Android P Preview 5 está disponible para los siguientes dispositivos (gracias a Project Treble):
Teléfono esencial
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 Android P en su dispositivo, simplemente vaya aquí y haga clic en "Obtener Beta" para su dispositivo. Llevarlo por el aire o rodarlo usted mismo: la elección es suya. Se adjuntan las instrucciones en el sitio.
Pero si no puede o no desea instalar Android P en el dispositivo, entonces nadie ha cancelado el emulador. Instrucciones de configuración aquí .

2. Encienda el propio bang programáticamente (si no hay hardware)


Aquí todo es simple: vaya a Sistema -> Opciones de desarrollador -> Simular una pantalla con un recorte.
Hay 3 opciones para elegir:
  • Esquina
  • Doble
  • Alto


Se ven de la siguiente manera:
EsquinaDobleAlto

3. Camina por las pantallas principales


Por supuesto, este caso será diferente para todos. Alguien tiene una lógica simple, alguien no. Daré un par de ejemplos de pantallas con diseño viajado que encontré en nuestra aplicación.
ExplorePerfil

Ahora veamos cuáles son las formas de eliminar defectos de diseño.

Sin levantar compileSdkVersion

Comenzando con la API 20, apareció la clase WindowInsets , que es un objeto Rect que describe las partes accesibles e inaccesibles de la pantalla. Junto con ellos, tales métodos aparecieron en View que podemos usar para procesar las coordenadas de partes inaccesibles de la pantalla:

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

Los detalles sobre cómo usarlos están aquí .

Hay dos formas de usar estos métodos:
a) coloque la etiqueta android:fitsSystemWindows="true" en el diseño de su diseño o vista;
b) hacerlo desde el código:

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

EraSe ha convertido

Actualice compileSdkVersion a la versión 28

En un futuro cercano, tendrá que cambiar a esta versión, entonces, ¿por qué no prepararse para esto ahora? Pero tenga cuidado si tiene pruebas unitarias en su proyecto (y espero que las tenga), el paquete JUnit se ha movido. Cómo conectarlo se describe aquí .

Entonces, ¿qué opciones nos ofrece Android P ahora?

A. WindowManager.LayoutParams tiene 3 nuevas banderas:

¿Cómo aplicar?

 window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 

B. Si la opción A no es adecuada para usted y necesita tener en cuenta la ubicación del corte desafortunado (por ejemplo, algo se muestra en la barra de estado, como un mensaje de conexión en Telegram), en este caso la nueva clase DisplayCutout ayudará.
Considere sus métodos:

Con ellos ya puedes hacer todo lo que sea suficiente para la imaginación. ¿Desea mover margin en el código en ellos? OnApplyWindowInsetsListener desea, manejarlo en OnApplyWindowInsetsListener y consumeDisplayCutout() . Quizás necesites manipulaciones más complejas. Daré un ejemplo simple de cómo denotar una explosión.

 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


EsquinaDobleAlto


Paisaje


Esquina
Doble
Alto

Entonces, como vemos, la franja nos traerá algunos inconvenientes y nos hará hacer gestos adicionales / manipulaciones adicionales. En principio, todo está resuelto. Lo principal es comenzar a eliminar las deficiencias de diseño lo antes posible para tener tiempo suficiente para la preparación. Haga frente con éxito a sus ediciones. ¡Que Google no rompa su juego!

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


All Articles