I have a drawing library, and with it I have a custom View. When any updates need to be done, the library calls the view's invalidate()
method. And then the onDraw()
method is called, and everything works just fine.
However, when I add the attribute of usesSdkVersion="14"
to my AndroidManifest.xml file
, this stops working. No longer is my view's onDraw()
method getting called anymore.
MORE INFO:
It seems that when I call invalidate()
as the result of a button push in my app, the View updates as expected. Also, there is one animation inside my library which is working correctly. So apparently sometimes it is working correctly. But most of the time, it is not getting redrawn. Is there any state that a custom View can be in that would cause the OS to skip redrawing it after invalidate()
is called?
From android 3.0, when using Hardware acceleration, the drawing of views is recorded and stored at the GPU.
So when you got two views: A above B, and you call B.invalidate
, B.onDraw
will be called and record to the GPU, but A.onDraw
will not be called because it's already recorded!
This is the different from non-hardware acceleration mode when all the views onDraw
been called.
by official documents:
However, because hardware acceleration is not supported for all of the 2D drawing operations, turning it on might affect some of your applications that use custom views or drawing calls. Problems usually manifest themselves as invisible elements, exceptions, or wrongly rendered pixels.
To remedy this, Android gives you the option to enable or disable hardware acceleration at the following levels:
Application
<application android:hardwareAccelerated="true" ...>
Activity
<application android:hardwareAccelerated="true"> <activity ... /> <activity android:hardwareAccelerated="false" /> </application>
Window
getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
View
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
I test in my view.
It seems like a bug in Android. Instead of invalidate() try to use method of the same name with four parameters:
view.invalidate(0,0,view.getWidth(), view.getHeight());
By the way, it is better practice to invalidate only that region, which is changing. Pass left, top, right, bottom coordinates of invalidated region.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With