Should I take view translation into account when overriding onDraw()? Or it is already applied to canvas translation?
I.e. should I execute
canvas.translate(getTranslationX(), getTranslationY());
in first line of onDraw()?
Do all transformations applied to canvas in onDraw() call persist in subsequent calls? I.e. should I suppose canvas is each time untransformed?
No, you do not need to do this. A View's translation is applied before onDraw is called.
As HardCoder points out, state changes that you make to the Canvas passed to onDraw will not persist to the next call to onDraw.
As far as I know the canvas is not persistant therefore you should execute the translate. However you can save the canvas and restore it:
http://maohao.wordpress.com/2009/09/30/canvas-save-canvas-restore/
Android View.onDraw() always has a clean Canvas
http://blahti.wordpress.com/2010/12/20/moving-views-in-android-part-1/
Related
Hi I am new to Android Canvas. I want to know how can I draw on canvas using a bitmap.
Basically I want to be able to draw multiple figures in my canvas dynamically. After reading about canvas I figured out this much that for each figure I may have to create a new bitmap attach a canvas to it draw a figure in that bitmap and finally draw that bitmap in the canvas of onDraw() method using drawBitmap function in order to view it on screen. Hope I am right till this part ? If not please correct me. I am open for your opinions and suggestions :)
Also I would like to know if I can apply onTouch event separately to the bitmaps or canvas created dynamically or it can be only applied to canvas of onDraw cause I want the images which are being drawn in my canvas to be able to move at users will?
You are right about the first part. However in second part u cannot add onTouch listener as u have said. As far as I know listeners can only be added to Views. And also its not like you are adding onTouch Listener to the canvas of the onDraw() method u are basically applying to the whole view a view cannot have two same listeners.
The Android View Class has a method called onDraw, and onDraw gets passed a canvas. Only the user never explicitly creates the canvas that gets passed and appears to have no other means by which to access it.
What is the canvas that gets passed to onDraw, where is it created and is there a way to access it?
Thank you for your help.
As concluded from Understanding Canvas and Surface concepts
A view implicitly has a canvas associated with it. When invalidate() is called from within a specific view, or for a specific view (i.e. View v and you then call v.invalidate()) the canvas associated with that view is sent to the View's onDraw method.
When a view contains other views, the hierarchical view tree is traversed and redrawn starting from the view that made the invalidate call.
ViewRootImpl, the topmost class in the view hierarchy, requests a Canvas for the entire visible window, and passes it to the top level ViewGroup of your Activity. Each ViewGroup then passes a concatenatedsubsetted version of this Canvas to each child View's draw() method.
As far as I know, it's not possible to manipulate the Canvas outside of onDraw() (and related methods).
You might try calling draw() yourself with a new instance of Canvas that you control. That won't draw anything onto the screen, but you'll be able to read the Canvas elsewhere in your class, convert it to a bitmap, etc. See this answer for an example: Convert view to bitmap on Android
I have a customview and it's background color must be changed every one or two seconds between two colors for example black and white.I can use canvas.drawARGB() and invalidate() to fill canvas with any color.But there are two constant colors that canvas can be colored and calling invalidate every one or two seconds reduces speed.So I guess if I have two canvas that first is colored white and second black and I change whole canvas in onDraw() it may be better than calling canvas.drawARGB().Is my guess true?And is it possible?
Note:
My purpose is to avoid of calling canvas.drawARGB() or canvas.setBitmap() or some things else.
If you are trying to change the background color I think a better and simpler approach is which is presented here in the accepted answer:
v.setBackgroundColor(0xFF00FF00); // Where v is your view
Or:
v.setBackgroundColor(Color.GREEN); // Where v is your view
This should be faster than filling the Canvas View with an specific color and then call invalidate()
I don't think that changing the whole canvas is possible or wise since the canvas object in ondraw method is all ready prepared for the view and the overhead needed to create a copy of it may be inefficient. However you can use the setBackgroundColor which will apply the color before the ondraw method gets called, see here the drawing paragraph. I think this is the correct approach because you are letting android to do the background assuming that it will use the fastest and the more efficient method.
Hope this helps...
you should change color of your paint object and pass that paint object to your canvas object.
I read about the invalidate overload that takes a rectangle, but I didn't understand how I can determine that rectangle when onDraw is called (if I have a custom view and implement onDraw). Do I have to keep it in a member variable, so I will have access to it and then redraw only that rectangle, or am I supposed to ignore it altogether and redraw everything, letting Android handle it so that only the rectangle is actually refreshed?
Thanks.
canvas.getClipBounds();
Additionally, anything you do in onDraw outside the invalidated region is ignored.
I am currently developing a single view android app using the simple invalidate/onDraw strategy, and have noticed that the canvas always appears erased prior to the invocation of the onDraw method. Does anyone know of a simple way to preserve the current canvas contents prior to the onDraw method call? Any help would be most appreciated.
Use a bitmap to store the last drawn state and in every onDraw method call, draw the bitmap to the canvas before anything else.