I have created a custom view to be shown in the action bar. It mostly works except sometimes on start I see a mirror copy of whatever I draw. The copy overlaps the original one but a few pixels away.
My onDraw() override is quite simple. All it does is draws an image that is centered in the canvas.
I am a bit confused. Am I expected to clear the canvas first in onDraw() method? Thank you in advance for your help.
It is confusing, but you'll notice in the custom view samples (that come with the sdk), the onDraw() method first calls canvas.drawColor() before anything else.
I assume it's not done automatically because it would be wasteful in the case where what you were drawing filled the entire view anyway. I just wish it was more clear that it is necessary in most cases.
Here is what I found out that others may find useful. If you set a background using setBackground(), the framework will actually draw the background before calling onDraw(). This background is drawn in the center. I too was drawing the background in onDraw() but I was drawing it from top-left. Hence, I was seeing the ghost image.
As Krylez mentioned, you may wish to call drawColor() as your first call in onDraw().
What I did was overrode setBackground() and its variations, and stored the background bitmap in a local variable.
Regards,
Peter
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.
on a canvas is it possible to draw text but make half of it not show up (as if it is being drawn partially off of the canvas, but actually not being off the canvas). i have an indicator on a "graph" with some text and it follows the point but I do not want the text to be drawn out of the graph portion (i am drawing other stuff outside that area).
I also have a background on the layout behind the canvas so I cannot just paint with a bitmap because that would cause some aspect ratio/sizing issues (wouldn't look good).
I have tried looking for answers all over Google, Stack overflow, and by experimentation with no avail. On Google I found many interesting things about drawing text on an android canvas but nothing that I was looking fore, I am pretty stumped, and I am starting to think that what I want is not even possible, and i may need to draw the text custom with points or figure out an alternative that looks just as good.
It's absolutely possible. Probably the fastest is to use clipRect to limit drawing to your graph portion. See this answer: Using clipRect - explanation
The reference on the various forms of clipRect is here: http://developer.android.com/reference/android/graphics/Canvas.html#clipRect(android.graphics.Rect, android.graphics.Region.Op)
If I recall, the whole operation will look something like:
yourCanves.save()
yourCanvas.clipRect(...)
yourCanvas.drawText(...)
yourCanvas.restore()
The restore() call serves to undo the clipRect so you can draw outside it for later drawing.
The simplest solution that popped in my mind, would be to cut using substring the text that you want to dispaly.
Example:
if(MyString >5){
canvas.drawText("VeryLongTe...");
}
I want to draw a bitmap to the canvas.
However, I am an inexperienced programmer and don't know how to make the canvas the main screen.
Basically, I want to draw a bitmap to the main activity using a canvas. I know how to draw bitmaps to canvases but it doesn't show up anywhere that I can see (with only one activity). I want the bitmap to show up on the main activity. Any tips?
Sorry if the wording is confusing, thanks for any help.
see these links. might think they may be helpful.
https://www.linux.com/learn/tutorials/707993-how-to-draw-2d-object-in-android-with-a-canvas
http://www.linux.com/learn/tutorials/703911-2d-drawing-with-android-motion-sensors
you can try searching online..
some example
http://www.edu4java.com/en/androidgame/androidgame2.html
or some game engine which will help you to develop game with proper memory management.
https://stackoverflow.com/questions/17163446/what-is-the-best-2d-game-engine-for-android
What you are trying to do is create your own CustomView. When you are putting a button or anything in your layout file that is actually a view. Android does allow you to create your own view to manually handle things on the screen. Games are usually implemented that way. They use customview by extending SurfaceView/GLSurfaceView.
As for the solution of your problem:
create a custom view by extending the View.
add all the constructor from superclass.
override onDraw method
onDraw method will pass you a canvas for you to draw
draw whatever you like(Bitmap, line ,....) using canvas
In your layout file include the customview you just created.
<my.packagename.MyCustomView android:width .... > </my.packagename.MyCustomView>
Hope this helps.
Also you will find lots good resources on how you can create your own customview.
I know how to draw paths on a canvas and understand how to undo/redo. But now I want to draw shapes (lines, circles, rectangles) that dynamically resize depending on how I drag them - just like we have in MS Paint.
If I use "drawLine", the line is there permanently with no way of erasing it and redrawing it to my new finger location. Same with circle as I want the circle to constantly change width as I drag my finger. So the old one has to erased (keeping all the other paths on the bitmap intact) and the new one drawn in its place.
Been searching a lot for this, but haven't come across how t do it. Maybe I'm using the wrong keywords, but I don't know. Any pointers?
Each time you move the finger, call the underlying view's invalidate() function, it will trigger erasing the entire background
public void invalidate ()
Since: API Level 1
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
Then redraw your shape based on your finger's new position.
Managed to do it. I misunderstood the way the offscreen drawing thing worked. The idea is to write to the bitmap only after you have the shape you want - ie on "touch up". Till then, draw the shape using the "canvas" object in on Draw...
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