Is it a good programming practice to call invalidate() inside onDraw()?
As per my understanding, calling invalidate() inside onDraw() is expensive and is not required if there is no change to the canvas.
Is invalidate() equivalent to an asynchronous version of onDraw()?
As per my understanding, they are equivalent. Correct me if I am wrong. Thank you.
Only call invalidate() if your data has changed and needs to be redrawn. You generally don't do this in onDraw(), because at that point you are drawing your current data, not changing it. (There are some cases where you may want to do this, such as for running animations, but generally I would recommend instead using a delayed message to control your own timing of the updates.)
Related
Okay so far when I have used SurfaceView I would override the draw method and then call it from a seperate thread. However, recently I tried to not override it but simply make all my canvas drawing calls in a custom method, and it worked. I would just do all my drawing the same way but instead of all the code being in overridden draw method, I would just put it all in another method and it worked anyways. So whats the point of overriding anything? I honestly still don't know how all the drawing works behind the scenes as its not explained...
For SurfaceView as you noticed yourself it makes no difference. There's no point of overriding draw and then calling it yourself from the separate thread.
The SurfaceView only have the method there because it inherits it from the View class, but because you're, in a separate thread, acquiring the lock to the canvas, drawing and then releasing, it doesn't matter if you pass it to the draw method, if you use directly on the thread run or some other Runnable
Maybe one could argue that it's more organised (and do never underestimate the importance of a well organised code), but it's not a necessity.
I am making an Android game in which some graphical elements move fast.
I am going to use Canvas but fear that the onDraw method will be called at irregular interevals making the fast elements move at irregular speeds.
Is there a way to make sure that the onDraw method is called at regular intervals.
Alternately if I can get the system time in msec I can take the difference between two consecutive calls to onDraw and based on the speed of these fast elements make the their movement smooth.
Kindly help,
Sameer
I am going to use Canvas but fear that the onDraw method will be called at irregular interevals making the fast elements move at irregular speeds
You should not update the position of objects in onDraw(), because:
Indeed, the method might not be called at predefined intervals
It is meant to draw objects, not update objects
Instead, update the objects/world in another method that you call at regular intervals using a timer.
After updating the world, call invalidate() on your View to trigger the onDraw() method. If your application has some spare time it will be called. If not, no problem since the world update method will keep on running and thus updating your world.
(Of course, if your application is too busy the view is never updated and you have problems to solve!)
Alternately if I can get the system time in msec I can take the difference between two consecutive calls to onDraw and based on the speed of these fast elements make the their movement smooth.
This is the way to go in the 'world update method'!
It will correct for the irregular timer intervals.
This is the situation
- My root layout is scrollview
- A custom view with multiple drawing operations is embedded in the layout
My problem is that if the layout is scrolled then customview.ondraw() is being called multiple times. Since there are many operations in the ondraw() I am getting a performance hit.
What is the best strategy out of this?
See the docs on View.setDrawingCacheEnabled(). Note you have to call getDrawingCache() in your onDraw implementation, and draw the returned bitmap if getDrawingCache() returns a non-null value. I'm not sure whether ScrollView will take care of calling setDrawingCacheEnabled automatically. You'll have to try it and find out. I think it does; but you still need to call getDrawingCache() in your onDraw routine.
That takes care of the non-hardware accelerated cases.
For hardware accelerated views, see the docs for setLayerType. It's far from a given that caching hardware accelerated views actually provides a performance improvement, so do this cautiously.
Forgot the name of the methods in Android, but there is a Swing demo with a split pane.
If there is a flag set to true ( update continuously) than the split panel is drawing wile you move the spit components. The same effect is at scroll too. You can use a draw, continuously and another only when the scrolling finished. The same thing is at iOS too.
You need to find which are those methods and embed your custom view drawing when is needed.
if i call invlidate() at the end of onDraw() function in a View, at what rate does the system refreshers?.
In emulator it takes around 1 second to call the method.
What are you using the canvas for? If you're doing a game or something that needs to be refreshed constantly you should really use a SurfaceView. That will take care of calling the draw method at regular intervals without you having to call invalidate. That said the refresh rate of a SurfaceView really depends on what you're drawing. If all you're doing is clearing it then it can do many hundreds of frames per second.
I'd like to include a simple draw feature on my app. A friend told me I can't use canvas because I need to control the frame buffer and not redraw the entire screen every for every frame. He suggested I find a openGL 2d engine. I've searched around and I've only found Rokon which doesn't have any documentation and the examples aren't quite what I need.
Any suggestions?
I don't really understand what the problem is?
If you simply wish to redraw some portion of the canvas you can use invalidate(rect).
http://developer.android.com/reference/android/view/View.html#invalidate()
Just create a custom veiw by extending the view class. in this custome view override the onDraw method. Android itself takes care of the pixels that have been changed and calling invalidate only refreshes the pixels that have been marked dirty