2012-05-18 9 views
26

Mi respuesta a this question fue aceptada, pero comencé a preguntarme cuándo exactamente se necesita invalidar() una Vista y cuándo no es necesario.¿Cuándo es necesario ejecutar invalidate() en una vista?

Después de un poco de pensamiento me vino a darse cuenta de que se debe trabajo más o menos así:

  • dibujo real de "todo" se produce después de onResume()
  • en partes "libres" de tiempo de la pantalla se puede volver a dibujar, pero sólo los que estaban invalidated (y todo por debajo)

por lo tanto, parecería, si cambio algo después onResume() (p. como respuesta a un clic del botón, debería invalidate() el View cambiado).

Sin embargo, a partir de lo que dice scana en this question, debe ser más complejo que eso y depende en ocasiones del método que se use.

E.g. de si se utiliza

lastClicked.setImageBitmap(); 

o

lastClicked.setImageResource(); 

Por lo tanto, cuando es necesario ejecutar invalidate() en una vista y cómo funciona realmente?

Respuesta

13

Por lo general, el sistema maneja el cambio de tamaño, ocultación, presentación y una tonelada de otras cosas para tus widgets automáticamente pero a veces tiene problemas si el búfer subyacente para píxeles dibujados o datos de respaldo ha cambiado o está obsoleto (se intercambia el recurso de imagen en una Vista o el conjunto de datos sin formato cambia). Esto ocurre porque no hay forma de que el sistema operativo pueda saber que los datos cambiaron de la manera específica en que lo hizo.

En estos casos en los que está tratando con el dibujo, hay que indicar al sistema que sus datos subyacente no está en un buen estado con Widget.invalidate() y la re-dibujo obtiene en cola en el hilo principal, justo como lo mencionaste.Dependiendo de la implementación del sistema y de la versión de Android, los cambios en el sistema varían, pero lo que hago normalmente es suponer que los recursos del sistema (matrices de bytes, matrices de caracteres, índices de recursos, dibujo manual en el contexto) no se rastrean y necesitan un invalidar y todo lo demás será manejado por el sistema.

+0

Algunas oraciones corrigen, pero el enfoque es incorrecto. !! -1 – ncm

54

(¿Se considera aceptar algunas respuestas)

En general, invalidate() medios 'vuelven a dibujar en la pantalla' y los resultados de una llamada de método onDraw() de la vista. Entonces, si algo cambia y debe reflejarse en la pantalla, debe llamar al invalidate(). Sin embargo, para los widgets integrados, rara vez, si es que lo necesita, debe llamarlo usted mismo. Cuando cambie el estado de un widget, el código interno llamará al invalidate() según sea necesario y su cambio se reflejará en la pantalla. Por ejemplo, si llama al TextView.setText(), después de hacer un montón de procesamiento interno (¿se ajustará el texto en la pantalla, necesita ser elipsado, etc.)? TextView llamará al invalidate() antes de setText() devuelve. Del mismo modo para otros widgets.

Si implementa una vista personalizada, deberá llamar al invalidate() siempre que el modelo de respaldo cambie y necesite volver a dibujar la vista. También se puede usar para crear animaciones simples, donde cambia el estado, luego llama al invalidate(), cambia el estado otra vez, etc.

+1

para completar esta respuesta, diría que muchas veces es importante verificar el código de los diversos métodos que puede utilizar en un widget para comprender cuándo hay una llamada invalidada e implementar un diseño para minimizarlos. por ejemplo, si tiene un diseño complejo, un solo TextView con wrap_content invalidará siempre() todo su diseño al final de cada llamada a setText(), en el otro extremo si logra obtener una dimensión fija solo el texto dentro la vista cambiará con el resultado de una GUI mucho más fluida. –

0

Recuerde que dibujar en la pantalla es un proceso frecuente, siempre que actualice una vista, ese cambio debe propocionarse y redibujarse para notificar dicho cambio. invalidate() es un método desencadenante, que señala forzar el reescritura de cualquier vista para la que desee mostrar los cambios.

Cuestiones relacionadas