2012-04-13 12 views
6

Tengo una biblioteca de dibujo, y con ella tengo una vista personalizada. Cuando se necesita realizar alguna actualización, la biblioteca llama al método invalidate() de la vista. Y luego se llama al método onDraw(), y todo funciona bien.View.invalidate() no parece llamar a View.onDraw()

Sin embargo, cuando agrego el atributo usesSdkVersion="14" a mi AndroidManifest.xml file, esto deja de funcionar. Ya no se llama más al método onDraw() de mi vista.

MÁS INFORMACIÓN: Parece que cuando llamo a invalidate() como resultado de presionar un botón en mi aplicación, la vista se actualiza como se esperaba. Además, hay una animación dentro de mi biblioteca que funciona correctamente. Entonces, aparentemente, a veces funciona correctamente. Pero la mayoría de las veces, no se vuelve a dibujar. ¿Hay algún estado en el que pueda estar una vista personalizada que haga que el sistema operativo omita volver a dibujarlo después de llamar al invalidate()?

+0

¿Aún lo llamas desde el hilo de la interfaz de usuario? de lo contrario, debe usar postInvalidate(). – Heinrisch

+0

Intenté cambiar el invalidate por postInvalidar solo para verificarlo, y el problema aún existe. – Rickster

+0

¿La aceleración de hardware está activada o desactivada? –

Respuesta

5

Desde android 3.0, cuando se utiliza la aceleración de hardware, el dibujo de las vistas se graba y almacena en la GPU.

Así que cuando usted tiene dos puntos de vista: A anterior B, y se llaman B.invalidate, B.onDraw se llamará y registro a la GPU, pero A.onDraw no se llamará porque ya está registrado!

Este es el modo de aceleración diferente del hardware cuando se llamaron todas las vistas onDraw.

2

de documentos oficiales:

Sin embargo, debido a la aceleración de hardware no es compatible para todas las operaciones de dibujo 2D, encendiéndolo podría afectar algunas de las aplicaciones que utilizan las vistas personalizadas o llamadas de dibujo. Los problemas generalmente se manifiestan como elementos invisibles, excepciones o píxeles renderizados incorrectamente.

Para remediar esto, Android le da la opción de activar o desactivar la aceleración de hardware en los siguientes niveles:

aplicación

<application android:hardwareAccelerated="true" ...> 

Actividad

.

Ventana

GetWindow() setFlags (WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);

Ver

myView.setLayerType (View.LAYER_TYPE_SOFTWARE, null);

Pruebo en mi vista.

1

Parece un error en Android. En lugar de invalidate() tratan de utilizar el método del mismo nombre con cuatro parámetros:

view.invalidate(0,0,view.getWidth(), view.getHeight()); 

Por cierto, es mejor práctica para invalidar solamente esa región, que está cambiando. Pase las coordenadas izquierda, superior, derecha e inferior de la región invalidada.

Cuestiones relacionadas