studio constraint clase cardview android android-layout android-view

clase - constraint layout android



Uso de forceLayout(), requestLayout() e invalidar() (5)

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

¿Cuándo serán llamados?


invalidate()

La llamada a invalidate() se realiza cuando desea programar un redibujado de la vista. Dará lugar a que se onDraw a onDraw tiempo (pronto, pero no de forma inmediata). Un ejemplo de cuándo una vista personalizada lo llamaría es cuando ha cambiado una propiedad de texto o color de fondo.

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

requestLayout()

Si algo acerca de su vista cambia que afectará el tamaño, entonces debe llamar requestLayout() . Esto desencadenará onMeasure y onLayout no solo para esta vista sino en toda la línea de las vistas principales.

Llamar requestLayout() no garantiza que se onDraw un onDraw (al contrario de lo que implica el diagrama en la respuesta aceptada), por lo que generalmente se combina con invalidate() .

invalidate(); requestLayout();

Un ejemplo de esto es cuando una etiqueta personalizada tiene su propiedad de texto modificada. La etiqueta cambiaría de tamaño y, por lo tanto, será necesario volver a medirla y volver a dibujarla.

forceLayout()

Cuando hay un requestLayout() que se llama en un grupo de vista principal, no es necesario que vuelva a medir y retransmitir sus vistas secundarias. Sin embargo, si un niño debe incluirse en la medición y retransmisión, puede llamar a forceLayout() en el niño. forceLayout() solo funciona en un elemento secundario si ocurre junto con un requestLayout() en su elemento primario directo. Llamar a forceLayout() por sí solo no tendrá ningún efecto ya que no desencadena un requestLayout() en el árbol de vista.

Lea estas preguntas y respuestas para obtener una descripción más detallada de forceLayout() .

Estudio adicional



Para comprender mejor las respuestas proporcionadas por François BOURLIEUX y Dalvik , sugiero que eche un vistazo a este impresionante diagrama del ciclo de vida de Arpit Mathur :


utiliza invalidate () en una vista que desea volver a dibujar, hará que se invoque onDraw (Canvas c) y requestLayout () hará que se ejecute de nuevo toda la representación de diseño (fase de medición y fase de posicionamiento). Debería usarlo si está cambiando el tamaño de la vista secundaria en tiempo de ejecución, pero solo en casos particulares, como restricciones de la vista principal (con esto quiero decir que la altura o el ancho de los padres son WRAP_CONTENT y así comparar los hijos antes de que puedan envolverlos nuevamente)


Esta respuesta no es correcta sobre forceLayout() .

Como puede ver en el código de forceLayout() simplemente marca la vista como "necesita una retransmisión" pero no programa ni activa esa retransmisión. La retransmisión no se realizará hasta que en algún momento en el futuro el padre de la vista haya sido distribuido por alguna otra razón.

También hay un problema mucho mayor al utilizar forceLayout() y requestLayout() :

Supongamos que ha llamado a forceLayout() en una vista. Ahora cuando se llama a requestLayout() en un descendiente de esa vista, Android llamará recurrentemente a requestLayout() en los antepasados ​​de ese descendiente. El problema es que detendrá la recursión en la vista a la que llamó 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 vista está esperando un diseño y llamar a requestLayout() en cualquier vista de ese subárbol no causará un diseño. Solo llamando a requestLayout() en cualquier vista fuera de ese subárbol romperá el hechizo.

Consideraría que la implementación de forceLayout() (y cómo afecta a requestLayout() debe romper y nunca debes usar esa función en tu código.