Estoy un poco confundida acerca de las funciones de forceLayout(), requestLayout() y invalidate() métodos de la View clase.

Cuando se les llama?

InformationsquelleAutor fiddler | 2012-12-13

5 Comentarios

  1. 316

    Para entender mejor las respuestas proporcionadas por François BOURLIEUX y Dalvik sugiero que eche un vistazo a este impresionante vista del ciclo de vida diagrama de Arpit Mathur:
    El uso de forceLayout(), requestLayout() y invalidate()

    • A menudo veo que requestLayout ser llamado directamente después de invalidar se llama, incluso veo que pasa en Android de código fuente para cosas como TextView, pero de acuerdo a este diagrama de hacerlo es redundante, ¿verdad? Entonces, żhay algún propósito para hacer eso?
    • Así que es una pregunta muy interesante, y para ser honesto, realmente no sé por qué se llaman los dos métodos, por ejemplo, en TextView. Pensé que tal vez se desea dibujar el View por última vez antes de cambiar su esquema de parámetros relacionados, pero que realmente no tiene ningún sentido si pensamos acerca de las llamadas que se invoca en la orden diferente (y que ellos llaman invalidate() justo después de requestLayout() en TextView así). Tal vez se merece otra pregunta en StackOverflow :)?
    • Sólo para señalar que el diagrama de arriba es limpia, pero puede ser engañoso. Creo que invalidate() también puede programar una MEDIDA que pase el punto de vista de la jerarquía ( el uso de ViewRoot ). Si el cambio visual es un simple bg cambio de color, entonces tenemos nada de que preocuparse MEDIDA de pase o de rendimiento. Pero la invalidación de la razón es un cambio de tamaño, por ejemplo, y luego MEDIR pasar también se supone para ser una patada y canalización de representación de los pasos deben ser muy parecidos ( o exactamente los mismos), como con requestLayout del.
    • (1/2): no creo que usted entiende los dos métodos (invalidate() y requestLayout()) correctamente. La finalidad de estos métodos es decirle a la View qué tipo de invalidación (como tú dices) que ha pasado. No es como el View decide qué camino a seguir después de llamar a uno de esos métodos. La lógica detrás de la elección de la View-ciclo de vida: la ruta es la elección del método apropiado para llamar a sí mismo. Si hay algo relacionado con el cambio de tamaño – requestLayout() debe ser llamado, si sólo hay un cambio visual sin un tamaño ha cambiado – debe llamar invalidate().
    • (2/2): Si usted cambia el tamaño de su View de alguna manera, por ejemplo, get actual LayoutParams de un View y modificarlas, pero NO llamar requestLayout o setLayoutParams (que llama a requestLayout internamente), entonces usted puede llamar a invalidate() tanto como usted desea, y el View no pasará a través de la medida-diseño de proceso, por lo tanto no va a cambiar su tamaño. Si usted no le dice a su View que su tamaño ha cambiado (con un requestLayout llamada al método), entonces el View va a suponer que no, y el onMeasure y onLayout no será llamado.
    • más información aquí –> stackoverflow.com/questions/35279374/…
    • Este diagrama es engañosa. Consulte aquí y aquí. Llamar requestLayout() no está garantizada en un onDraw.
    • Hey @BartekLipinski puede usted por favor me ayude con este stackoverflow.com/questions/49952965/…

  2. 104

    invalidate()

    Llamar invalidate() se realiza cuando se desea programar un rediseño de la vista. Esto resultará en onDraw ser llamado con el tiempo (pronto, pero no inmediatamente). Un ejemplo de cuando una vista personalizada llamarlo cuando un texto o el color de fondo de la propiedad ha cambiado.

    La vista se vuelve a dibujar, pero el tamaño no va a cambiar.

    requestLayout()

    Si algo acerca de su punto de vista los cambios que afectarán el tamaño, entonces usted debe llamar a requestLayout(). Esto desencadenará onMeasure y onLayout no sólo para este punto de vista, sino de todo el camino hasta la línea de los puntos de vista de los padres.

    Llamar requestLayout() es no se garantiza el resultado en un onDraw (contrario a lo que en el diagrama de la aceptó respuesta implica), por lo que se suele combinar con invalidate().

    invalidate();
    requestLayout();

    Un ejemplo de esto es cuando una etiqueta personalizada tiene su propiedad text cambiado. La etiqueta de cambio de tamaño y por lo tanto necesita ser vuelto a medir y dibujar.

    forceLayout()

    Cuando hay un requestLayout() que se llama en una vista principal del grupo, no es necesario necesario volver a medir y relayout su hijo vistas. Sin embargo, si un niño debe ser incluido en el de volver a medir y relayout, entonces usted puede llamar a forceLayout() en el niño. forceLayout() sólo funciona en un niño, si se produce en conjunción con un requestLayout() en su matriz directa. Llamar forceLayout() por sí mismo no tendrá ningún efecto ya que no desencadenar una requestLayout() encima de la vista de árbol.

    Leer este Q&A para una descripción más detallada de forceLayout().

    Más estudio

  3. 25

    Aquí usted puede encontrar algunos de 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 calcular el tamaño de la vista en la pantalla.

    • ¿forceLayout() entonces ?
    • este método solo establece dos indicadores: PFLAG_FORCE_LAYOUT y PFLAG_INVALIDATED
    • ¿Cuáles son las consecuencias de configuración de los indicadores de entonces?
    • La consecuencia parece ser que este indicador reemplaza medida de caché (vistas usar caché para medir más rápido en el futuro para la misma MeasureSpec); vea la línea 18783 de View.java aquí: github.com/android/platform_frameworks_base/blob/master/core/…
  4. 3

    utilizar invalidate() en una vista que desea volver a dibujar, que va a hacer de su onDraw(Canvas c) para invocar, y requestLayout() hará que todo el procesamiento de diseño ( medición de fase y el posicionamiento de la fase) ejecutar de nuevo. Se debe utilizar si desea cambiar el hijo de la vista de su tamaño en tiempo de ejecución, pero sólo en casos particulares como las limitaciones de la vista principal(me refiero a que el padre de la altura o la anchura son WRAP_CONTENT y así coincidir con la medida de los niños antes de que puedan envolver de nuevo)

  5. 3

    Esta respuesta no es correcta acerca de forceLayout().

    Como se puede ver en el código de forceLayout() simplemente marcas el punto de vista como «necesita un relayout» pero no es ni de programación ni de gatillo que relayout. El relayout no va a suceder hasta que en algún punto en el futuro, a la vista del padre, se puso, por algún otro motivo.

    También hay una mucho más grande problema al utilizar la forceLayout() y requestLayout():

    Digamos que usted ha llamado forceLayout() en una vista. Ahora cuando se llama a requestLayout() en un descendiente de ese punto de vista, Android se llama recursivamente a requestLayout() en que el descendiente de antepasados. El problema es que va a dejar a la recursividad a la vista en la que usted ha llamado forceLayout(). Por lo que el requestLayout() llamada nunca alcanzará el punto de vista de la raíz y por lo tanto nunca programar una fase de diseño. Todo un subárbol de la vista de jerarquía está a la espera de un diseño y un llamamiento requestLayout() en cualquier vista de que el subárbol no va a causar un diseño. Sólo llamando a requestLayout() en cualquier vista, fuera de ese subárbol va a romper el hechizo.

    Me gustaría considerar la aplicación de forceLayout() (y cómo afecta a requestLayout() a estar roto y nunca se debe utilizar esa función en el código.

    • Hola! Cómo ha venido usted con que escribe? Está documentado que en algún lugar?
    • Lamentablemente no documentado y probablemente ni siquiera la intención. Me imaginé que fuera por investigar el código de View y corriendo hacia mi mismo el problema & depurando.
    • Entonces tengo curiosidad acerca de la finalidad de forceLayout() API: no, en realidad la fuerza de una fase de diseño, sino que sólo cambia una bandera que es la que se observa en onMeasure(), pero onMeasure() no será llamado a menos que requestLayout() o explícito View#measure() se llama. Eso significa, que forceLayout() debe ser emparejado con requestLayout(). Por otro lado, ¿por qué entonces a realizar forceLayout() si aún necesito para realizar requestLayout()?
    • no, usted no tiene que. requestLayout() hace todo lo que forceLayout() también lo hace.
    • Consulte esta respuesta de cómo forceLayout podría ser adecuadamente utilizado en el código.
    • faltó que uno, gracias! Muy interesante el análisis. La intención de uso de forceLayout tiene sentido. Así que al final es simplemente muy mal con nombre y documentada.

Dejar respuesta

Please enter your comment!
Please enter your name here