Uso de forceLayout (), requestLayout () e invalidate ()

Estoy un poco confundido acerca de los roles de los forceLayout() , requestLayout() e invalidate() de la clase View .

¿Cuándo serán llamados?

Para comprender mejor las respuestas proporcionadas por François BOURLIEUX y Dalvik te sugiero que eches un vistazo a este impresionante diagrama del ciclo de vida de la vista de Arpit Mathur : Introduzca aquí la descripción de la imagen

invalidate()

Llamar invalidate() se realiza cuando se desea programar un nuevo trazado de la vista. onDraw en onDraw se llama eventualmente (pronto, pero no inmediatamente). Un ejemplo de cuando una vista personalizada lo llamaría es cuando una propiedad de texto o de color de fondo ha cambiado.

La vista se volverá a dibujar pero el tamaño no cambiará.

requestLayout()

Si algo acerca de su vista cambia, esto afectará al tamaño, entonces debe llamar a requestLayout() . Esto activará onMeasure y onLayout no sólo para esta vista, sino todo el camino hasta la línea de las vistas de los padres.

Llamar requestLayout() no está garantizado para dar lugar a un onDraw (contrariamente a lo que implica el diagrama en la respuesta aceptada), por lo que suele combinarse con invalidate() .

 invalidate(); requestLayout(); 

Un ejemplo de esto es cuando una etiqueta personalizada tiene su propiedad de texto cambiada. La etiqueta cambiaría el tamaño y por lo tanto necesitaría ser re-medida y rediseñada.

forceLayout()

Llame a forceLayout() si sólo desea retransmitir el contenido de su propia vista, pero no necesita activar la nueva medición de todo el árbol de vistas (todas las vistas de los padres). Si tuviera un ViewGroup personalizado que no cambiara su propio tamaño, pero que necesitara remesar y retransmitir a sus hijos, esta sería una situación apropiada para llamar a forceLayout() .

Básicamente, llamar a requestLayout() da como resultado una llamada a parent.requestLayout() , pero llamar a forceLayout() no.

Estudio adicional

  • Creación de una clase de vista: Añadir propiedades y eventos (documentos útiles)
  • Ver documentación
  • View código fuente

Aquí puede encontrar alguna respuesta: http://developer.android.com/guide/topics/ui/how-android-draws.html

Para mí, una llamada a invalidate() sólo actualiza la vista y una llamada a requestLayout() actualiza la vista y calcula el tamaño de la vista en la pantalla.

Usted usa invalidate () en una vista que desea volver a dibujar, hará que su onDraw (Canvas c) sea invocado, y requestLayout () hará que todo el renderizado de layout (fase de medición y fase de posicionamiento) se ejecute de nuevo. Debería usarlo si está cambiando el tamaño de la vista secundaria en tiempo de ejecución, pero sólo en casos particulares como las restricciones de la vista principal (por eso me refiero a que la altura o el ancho de los padres son WRAP_CONTENT y por lo tanto miden los niños antes de que puedan volver a envolverlos)

Esta respuesta no es correcta sobre forceLayout() .

Como se puede ver en el código de forceLayout() simplemente marca la vista como "necesita un relayout" pero no programa ni dispara ese relayout. El relayout no ocurrirá hasta que en algún momento en el futuro el padre de la visión fue presentado por alguna otra razón.

También hay un problema mucho mayor cuando se utiliza forceLayout() y requestLayout() :

Digamos que has llamado forceLayout() en una vista. Ahora, al llamar a requestLayout() en un descendiente de esa vista, Android recursivamente llamará requestLayout() a los antepasados ​​de ese descendiente. El problema es que detendrá la recursión en la vista en la que has llamado forceLayout() . Por lo tanto, la llamada requestLayout() nunca llegará a la raíz de la vista y, por lo tanto, nunca programará un pase de diseño. Un subárbol completo de la jerarquía de vistas está esperando un diseño y la requestLayout() en cualquier vista de ese subárbol no provocará un diseño. Solamente llamar a requestLayout() en cualquier vista fuera de ese subárbol romperá el hechizo.

Consideraría la implementación de forceLayout() (y cómo afecta a requestLayout() para ser roto y nunca debe utilizar esa función en su código.

  • Android: fitsSystemWindows y newline interfieren con bottomSheets
  • No se puede mostrar 2 instancias de mi SurfaceView personalizado
  • Animar las dimensiones superior e inferior de una vista
  • ¿Es posible tomar una captura de pantalla de una vista, sin mostrar la vista?
  • Animación extraña en la Galería cuando se solicita un invalidate a sus hijos
  • ¿Cómo mantener los atributos de diseño en la vista personalizada android combinada?
  • Cómo deshabilitar el desplazamiento de HorizontalScrollView dentro de ViewPager
  • EditText no desplazable dentro de ScrollView
  • Cómo implementar Swipe en Android juego sin vista
  • ¿Hay una manera de localizar de forma programática todas las ventanas dentro de una aplicación determinada?
  • Cambio de vista de la aplicación de Android en lugar de emulador
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.