¿Por qué requestLayout se llama directamente después de invalidar

Estoy aprendiendo acerca de las vistas personalizadas y quería aprender acerca de invalidate() y requestLayout() .

Consulte esta respuesta y su diagrama:

Https://stackoverflow.com/a/25846243/4243687

invalidate() indica a Android que el estado de la vista ha cambiado y necesita ser redibujado.

requestLayout() significa que el tamaño de la vista puede haber cambiado y necesita ser re-medido, y luego volver a dibujar.

invalidate() invocará dispatchDraw() , draw() y onDraw() por lo que vuelve a mostrar la vista.

requestLayout() por otro lado hace casi todo, desde medir hasta volver a renderizar.

¿Por qué tantos ejemplos (por ejemplo, el código fuente de TextView ) llaman invalidate() y luego requestLayout() derecha en la línea siguiente?

invalidate() se utiliza específicamente para volver a dibujar el contenido de su vista. El redibujo no ocurre sincrónicamente. En su lugar, indica la región de su vista como no válida para que se vuelva a dibujar durante el ciclo de procesamiento siguiente.

requestLayout() debe utilizar cuando algo dentro de él posiblemente ha cambiado sus dimensiones. En este caso, la vista principal y todos los demás padres de la jerarquía de vista tendrán que reajustarse a través de un pase de disposición.

Si no está haciendo nada a su vista que cambiaría su tamaño, entonces no tiene que llamar a requestLayout() .

Si vuelves a mirar los lugares en el código de TextView donde requestLayout() está siendo llamado, estará en métodos donde los límites de la vista se verán afectados. Por ejemplo, setPadding() , setTypeface() , setCompoundDrawables() , etc.

Por lo tanto, cuando requestLayout() se llama, debe ser emparejado con una llamada a invalidar para asegurarse de que toda la vista se vuelve a dibujar.

Extracto pertinente del libro Expert Android que responde a la pregunta:

Debido a que el evento onClick ha provocado que las dimensiones cambien, nuestra vista debe hacerse más grande y tener más espacio. ¿Cómo se expresa esa necesidad de Android, Bueno, solicitamos Layout (). Este método sube la cadena, marcando cada padre de vista que necesita ser re-medido. Cuando el padre final obtiene esta solicitud (la raíz de la vista), el padre programa un recorrido de diseño. Un trazado de disposición puede o no resultar en onDraw, aunque en este caso debería. Como una buena práctica de programación, también llamamos invalidate () para asegurar la fase de dibujo también.

Después de ver el diagrama siguiente , tenía la impresión de que llamar a requestLayout() eventualmente resultaría en un onDraw .

Introduzca aquí la descripción de la imagen

Por lo tanto, no habría necesidad de llamarlos juntos porque sería redundante.

 invalidate(); requestLayout(); 

Sin embargo, resulta que ese diagrama es engañoso. Algunas vistas pueden de hecho invalidarse cuando hay un cambio de diseño, pero esto no es una certeza. Llamar requestLayout() no está garantizado para dar lugar a onDraw se llama.

Mi fuente (gracias a este comentario ) es el Romain Guy (que es un ingeniero de Android en Google):

RequestLayout () no conduce a un pase de dibujo, pero algunas vistas pueden reaccionar a un cambio de diseño invocando invalidate.

Por lo tanto, para estar seguro de que un relayout dará como resultado un redibujo, entonces debe emparejar un invalidate() con requestLayout() . (Lo contrario no es cierto, sin requestLayout() sólo necesita un redibujo, entonces no hay necesidad de llamar a requestLayout() . Un único invalidate() hará.)

Documentos de Android: Creación de una clase de vista

 public boolean isShowText() { return mShowText; } public void setShowText(boolean showText) { mShowText = showText; invalidate(); requestLayout(); } 

Observe que setShowText invoca invalidate () y requestLayout (). Estas llamadas son cruciales para asegurar que la vista se comporte de forma fiable. Debe invalidar la vista después de cualquier cambio en sus propiedades que pudiera cambiar su apariencia, para que el sistema sepa que debe volver a dibujarse. Asimismo, debe solicitar un nuevo diseño si cambia una propiedad que podría afectar al tamaño o la forma de la vista. Olvidar estas llamadas de método puede causar errores difíciles de encontrar.

  • Envoltura de texto uniforme en TextView
  • ConstraintLayout vistas en esquina superior izquierda
  • Cómo hacer aplicaciones hermosas y con estilo como Timely
  • Detectar clics largos en una vista personalizada?
  • ¿Qué significa el parámetro LayoutInflater attachToRoot?
  • Uso de surfaceView para capturar un video
  • Cómo deshabilitar el desplazamiento de HorizontalScrollView dentro de ViewPager
  • Android - Color de fondo con diferentes colores y ángulos
  • Cómo centrar una vista dentro de un diseño Android?
  • ¿Cómo puede una vista detectar cuando se está conectando a su padre?
  • IBM Worklight - ¿Cómo habilito la depuración de WebView en Android?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.