Red de conocimiento informático - Computadora portátil - El proceso de dibujo de la vista personalizada de Android (Parte 1)

El proceso de dibujo de la vista personalizada de Android (Parte 1)

Serie de artículos sobre el proceso de dibujo

Trilogía de visualización de Android:

Hemos analizado:

Las dos tareas más importantes son: Determinar el área rectangular donde se puede dibujar Vista/Grupo de Vistas.

A continuación, analizaremos cómo dibujar los gráficos requeridos en esta área determinada.

En esta publicación de blog, aprenderá:

Android proporciona dos clases básicas para Ver:

Sin embargo, ViewGroup no especifica cómo diseñar las subvistas. En su interior se acuerdan: ¿están apilados uno encima del otro? ¿O colocado horizontal o verticalmente? Lo mismo ocurre con las vistas. No se ponen de acuerdo sobre qué tipo de contenido se muestra: ¿un rectángulo, un círculo, un triángulo, una imagen, un texto o una forma irregular? ¿Necesitamos darnos cuenta de esto nosotros mismos?

No es así. Afortunadamente, Android ha tenido en cuenta estas necesidades y ha prefabricado algunos grupos de vistas y vistas de uso común para facilitar el desarrollo.

Por ejemplo:

Subclases heredadas de ViewGroup

Subclases heredadas de View

Aunque las subclases View/ViewGroup derivadas anteriormente nos proporcionan con gran comodidad, pero son solo controles comunes para escenarios de aplicaciones comunes. Si queremos lograr efectos más complejos, como barras de progreso onduladas, esferas brillantes, etc., estos controles del sistema son inútiles y no es necesario crear miles de controles extraños por adelantado. Para esto necesitamos vistas/grupos de vistas personalizados.

En términos generales, las vistas/grupos de vistas personalizados tienen los siguientes tipos:

3 no se usa comúnmente a menos que el diseño sea especial. 1, 2 y 4 se utilizan con más frecuencia, y por "vista personalizada" normalmente nos referimos a 4.

A continuación, veamos qué es 4 y veamos si tiene una vista personalizada.

Consulte MyView en xml

El efecto es el siguiente:

La parte negra es el fondo de su diseño principal.

El rectángulo rojo + círculo amarillo es el efecto dibujado por MyView.

Lo anterior es la implementación de Vista personalizada más simple. Extraemos los puntos clave y los resumimos de la siguiente manera:

De la demostración anterior, podemos ver que solo necesitamos reescribir onDraw. (xx) Método. Se pueden dibujar los gráficos requeridos.

Echemos un vistazo al método onDraw(xx) predeterminado de View:

Descubrimos que la implementación de este método está vacía, por lo que las clases heredadas de View deben anular el método onDraw(xx) para dibujar. Los parámetros pasados ​​por este método son: Tipo de lienzo.

El lienzo generalmente se llama lienzo cuando se traduce. En el objeto Canvas que anula onDraw (xx), también necesitamos un lápiz para tener el lienzo. Este lápiz es Paint, que generalmente se llama pincel cuando se traduce. Combina los dos y podrás divertirte pintando.

Es posible que hayas notado que Paint no se aprobó al llamar a

en la demostración. ¿No necesitamos Paint? De hecho, cuando llamas a este método, se genera automáticamente un objeto Paint en la parte inferior.

Como puedes ver, la capa subyacente inicializa Paint y le da el color establecido en la capa Java.

onDraw(xx) es relativamente simple. Abra un lienzo y el efecto es dibujar.

Imagínese cómo se genera este Canvas, es decir, quién llama a onDraw(xx).

Usando la función de asociación, los dos grupos ya mencionados en los procesos de Medición y Diseño son muy similares:

Entonces, ¿el proceso de Dibujo también es un grupo de este tipo? Al ver onDraw (xx), ¿draw (xx) no está muy lejos?

Sí, de hecho existe un método draw(xx):

Como puedes ver, draw(xx) se divide principalmente en dos partes:

Si Ya sea la rama A o B, hay varios pasos de dibujo.

Normalmente, la jerarquía de una única Vista se divide en:

El contenido dibujado más tarde puede ocultar el contenido dibujado antes.

Para ViewGroup, la jerarquía se divide en:

Echemos un vistazo a los 4 puntos clave de la anotación de la rama A:

(1)

onDraw(canvas)

Como se analizó anteriormente, para una sola Vista, onDraw(xx) es una implementación vacía y requiere que personalicemos el dibujo.

Y para ViewGroup, no existe una implementación específica. Si onDraw(xx) se anula en un ViewGroup personalizado, ¿se ejecutará? No por defecto. Para análisis, visite:

Por qué no se llama onDraw de Android ViewGroup

(2)

despachoDraw (canvas), vea la implementación en View.java:

Se descubre que es una implementación vacía y luego verifica la implementación en ViewGroup.java:

Se descubre que es una implementación vacía. java:

Es decir, para una sola Vista, debido a que no hay un subdiseño, no es necesario distribuir Draw, pero para un ViewGroup, su subdiseño debe activarse para comenzar. El proceso de sorteo (análisis posterior de este proceso), se puede comparar con el procesamiento del proceso de distribución de eventos de View y ViewGroup. Si está interesado, vaya a:

El evento de entrada de Android se envía al final del receptor Ver (3)

(3)

Superposición, como sugiere el nombre, es ""Superponer algo", que ocurre después de dibujar el contenido y antes de dibujar el primer plano. ¿Cómo funciona?

Lo anterior es configurar OverLay para ViewGroup, el efecto es el siguiente:

Es posible que hayas notado que esto es casi lo mismo que configurar OverLay, pero en realidad hay una diferencia. En onDrawForeground (xx), el tamaño del elemento de diseño cambiará al mismo tamaño que la vista, y el tamaño establecido previamente para el elemento de diseño no será válido. Así es como funciona:

Como puedes ver, todos los ViewGroups están cubiertos por el primer plano.

Echemos un vistazo al enfoque de la rama B: efecto de degradado de borde

Echemos un vistazo al efecto de degradado de borde de TextView:

Agregue estos dos parámetros.

De hecho, algunos controles que vienen con el sistema también usan este efecto, como NumberPicker y YearPickerView

Lo anterior es el efecto de NumberPicker. Puedes ver que tiene una vertical. gradiente.

onDraw(xx) y draw(xx) en View.java no se anulan en ViewGroup.java.

Para despachoDraw(xx), la implementación en View.java está vacía. El dibujo del subdiseño se inicia en ViewGroup.java.

Echemos un vistazo a los dos puntos principales del marcado:

(1)

El propósito de configurar el relleno es dejar un cierto espacio en el subdiseño, por lo tanto, cuando se establece el relleno, el lienzo del subdiseño debe recortarse de acuerdo con el relleno. La etiqueta de juicio es:

FLAG_CLIP_TO_PADDING está establecido en verdadero de forma predeterminada

FLAG_PADDING_NOT_NULL Siempre que el relleno no sea 0, la etiqueta se aplicará.

En otras palabras: siempre que haya un relleno que no esté establecido en 0, es necesario recortar el área de visualización del subdiseño.

¿Es posible evitar que un subdiseño recorte el área de visualización?

La respuesta es sí.

Considere una situación en la que utilizamos un RecyclerView y necesitamos establecer paddingTop = 20px. El efecto de esto es que el elemento RecyclerView se muestra a 20 píxeles de la parte superior, pero al desplazarse nunca se desplaza hacia la parte superior, lo que no parece amigable. Esto es lo que hace el recorte anterior, es necesario desactivarlo. Esto se puede lograr configurando:

Por supuesto, también se puede configurar en xml:

(2)

drawChild(xx)

A juzgar por el nombre del método, parece estar llamando al subdiseño para dibujar.

Hay dos situaciones para child.draw(x1,x2,x3):

Las funciones específicas y las diferencias entre los dos se analizarán en el próximo artículo, ya sea hardware dibujo acelerado o El software acelera el dibujo y eventualmente llamará al método View.draw(xx), que se analizó anteriormente.

Tenga en cuenta que dibujar(x1,x2,x3) no es lo mismo que dibujar(xx) y no debe confundirse.

Representado por un diagrama:

Conexión del proceso de dibujo Ver/ViewGroup:

Generalmente, generalmente personalizamos la Vista y anulamos su método onDraw(xx), así es. ¿Es necesario dibujar el contenido de ViewGroup?

Sí, por ejemplo, puede consultar el dibujo de RecyclerView ItemDecoration, que utiliza el orden de dibujo de ViewGroup draw(xx), ViewGroup onDraw(xx) y View onDraw(xx) para realizar líneas divisorias y agrupación de títulos flotantes y otras funciones.

Esta publicación está basada en Android 10.0.