I have a custom view that represents simple gameboard with several tiles. I have a 2-d array that stores the currently displayed image (0 for no image) for a tile.
Currently within my onDraw() method I loop through the array and display the images for the tiles. However the only time I invoke invalidate() without any args is when I reset the board. In all other places I only invoke an invalidate(Rect) for the required tile that needs to be updated.
Is this above implementation of onDraw() in-efficiently drawing the view? If so what would be a better way to do this? (also does invoking invalidate(Rect) guarantee updating only the 'Rect' region OR is this just a recommendation to Android that may be ignored?).
Appreciate any clarifications with this.
Is this above implementation of onDraw() in-efficiently drawing the view?
It is good enough. Otherwise you'd like to learn OpenGL to make use of hardware acceleration in your drawings, but all of this depends on if your tiles are changing every frame or how many tiles you have.
also does invoking invalidate(Rect) guarantee updating only the 'Rect' region OR is this just a recommendation to Android that may be ignored?
It updates the Rect area, infact Romain Guy uses invalidate(Rect) for the default home launcher application in order to not update the whole screen everytime the home screen needs an update.
Related
I need update a small portion of a custom view in order to display a small animation. The rest portion of the view has only static image. The most straightforward would be to obtain the canvas of the view and update only that particular portion directly. But I can't really find anyway to get the view's canvas object outside of the view::onDraw method.
The only alternative I know is this: call view::invalidate() with a specified rectangle to minimize the drawing flicker. I have the code to update the entire view within onDraw. So the best thing to do is to detect the clipping rect and only run the code to update the specified area, in order to minimize CPU usage as well?
I guess I will try to answer this question myself to the best my knowledge so far.
There is no direct access to the canvas outside of the onDraw method.
Although we can detect the clipping rect with the function Canvas.getClipBounds(), the getClipBounds function always return the entire view area if GPU is enabled. When GPU is not used, getClipBounds() returns the actual dirty area. Since there is a GPU in most phones, it makes the function getClipBounds pretty much useless.
In the project I am working on I decided to use SurfaceView instead of a custom double buffered medium. It provides everything I need and it's already double buffered.
The problem is that it wont let me specify multiple dirty rectangles to redraw.
SurfaceView.lockCanvas(Rect) only allows single rectangle and without parameter it's pretty expensive to redraw whole thing. Another solution to call lockCanvas(Rect) for each Rect causes eye-bleeding blinking in the screen, obviously.
Do you have any solution giving the opportunity staying inside Android API field, if not do you have any external alternatives I can use?
If you know the dirty areas before you need to call lockCanvas (sounds like you might), you could calculate a "super rectangle" that locks an area that contains all of your rectangle. For example if your rectangles are (using l,r,t,b coordinates) [0,10,0,20] and [15,30,10,35], your super rectangle would be [0,30,0,35].
I have an android app I have written, that basically has a custom overlay, in this overlay I have overwritten the DRAW method to draw something on a canvas and at the end of my DRAW override, I call the super DRAW passing in the canvas I have painted.. the result is, every time the map is modified in anyway my custom overlay is redrawn as expected.
Now, I am trying to accomplish the same thing on iPhone and am getting a little confused.
Basically I need something drawn in the top right corner of the map every time a redraw occurs of the map. The drawin will change change with every update as well so can't simply be put a view over the map and pass touches through etc.
So, I guess the question is, what is the euivalent of the DRAW method in iOS.. how would I roughly accomplish this same thing? There are MKOverlayView in the API, but there seem to be some significant differences.. So, how do I put something say at 10x10 over the map, whos size is variable and make sure every time the map is moved, scaled or otherwised interacted with this object is redrawn at location 10x10 on the screen.
The docs for MKMapView state that you should not subclass MKMapView, so you can't / shouldn't override the drawRect method. You could add a UIView, though, and override drawRect to do your custom drawing.
I coded an android application which is measuring heart rate from camera input. I needed to desing an ECG animation to the application. I know that ECG isn't related. But I'll try to show the sign according to heart rate. Which method do I need to use? Drawing animation into a View object from layout or Drawing graphics directly to a Canvas. And if you give some clues I'll be very appreciated.
To do real time graphing of ECG data...which is what I am coding right now, you need to create a custom view. Then in the onDraw method you use your canvas to draw a bitmap. Then inside the custom I also implement a Runnable that paints the line using drawline, and then invalidates(). I'd show you code but its proprietary since everything I found did not measure up to the speeds I had to graph.
It depends how real-time you need your data. If a lower framerate is sufficient, then I would recommended subclassing the View class and overriding the onDraw method. From there you can draw directly onto the canvas. Just make sure to call invalidate on the view after your data changes to make sure onDraw gets called.
If a faster framerate is required, then you probably want to use a SurfaceView. Google has a Lunar Lander example that does a good job of that. But note some bugs have been found in the example, so use it as a guide not as law.
Lunar Lander:
http://developer.android.com/resources/samples/LunarLander/index.html
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