Recommend Reading: Draw Animation on Canvas Example
Android provide a full functions on Graphics. Commonly, we can use 2D graphics library and OpenGL ES 1.0 for 3D graphic. In this post, I gonna to introduce the 2D graphics, and give you a 2D graphics canvas example. Usually, when we try to draw 2D graphics, as android developer page say, we have two ways to choose:
- Draw your graphics or animations into a View object from your layout.
- Draw your graphics directly to a Canvas.
Draw graphics directly to a Canvas is a little bit complicated. You can go to the android developer page for farther details. The following example will show you how to draw a bitmap on the canvas, when you click the canvas.
Download And Try APK File
As some friends gave me the feed back that the old application would crash after running for a while. So I improve this example code a little bit to fix this problem. And some people also don’t know how to use this application. They just saw a black screen when they started to run the demo. If you read the example code, you will understand that you need to touch the screen to start the drawing process.
New Update:
- Fix the application crashing bug.
- Add one text instruction
Check the latest android canvas example apk here
As android dev guide says, when you’re writing an application in which you would like to perform specialized drawing and/or control the animation of graphics, you should do so by drawing through a Canvas. When we do so, we will put our drawing code in onDrwa() callback method, and Canvas will be pass from the function parameter. And we also can get a canvas by calling SurfaceHolder.lockCanvas()
;
In my canvas example, we will put a SurfaceView on the stage, and when you click the surfaceview, it will draw the bitmap image on the canvas. This is the main.xml example:
<!--?xml version="1.0" encoding="utf-8"?--> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.jms.DrawImage.DrawCanvas android:id="@+id/SurfaceView01" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout>
There is our customized class DrawCanvas
, while extends from SurfaceView
:
public class DrawCanvas extends SurfaceView implements Callback { private CanvasThread canvasThread; public DrawCanvas(Context context) { super(context); // TODO Auto-generated constructor stub } public DrawCanvas(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub this.getHolder().addCallback(this); this.canvasThread = new CanvasThread(getHolder()); this.setFocusable(true); } public DrawCanvas(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub } public void startDrawImage() { canvasThread.setRunning(true); canvasThread.start(); } @Override public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder arg0) { // TODO Auto-generated method stub } @Override public void surfaceDestroyed(SurfaceHolder arg0) { // TODO Auto-generated method stub boolean retry = true; canvasThread.setRunning(false); while(retry) { try { canvasThread.join(); retry = false; } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub Bitmap sweet = BitmapFactory.decodeResource(getResources(), R.drawable.sq); canvas.drawColor(color.black); canvas.drawBitmap(sweet, 0, 0, null); } private class CanvasThread extends Thread { private SurfaceHolder surfaceHolder; private boolean isRun = false; public CanvasThread(SurfaceHolder holder) { this.surfaceHolder = holder; } public void setRunning(boolean run) { this.isRun = run; } @Override public void run() { // TODO Auto-generated method stub Canvas c; while(isRun) { c = null; try { c = this.surfaceHolder.lockCanvas(null); synchronized(this.surfaceHolder) { DrawCanvas.this.onDraw(c); } } finally { surfaceHolder.unlockCanvasAndPost(c); } } } } }
Here is the Activity code example:
public class DrawImage extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); DrawCanvas mycanvas = (DrawCanvas)findViewById(R.id.SurfaceView01); mycanvas.setOnClickListener(clickListener); } private OnClickListener clickListener = new OnClickListener() { private boolean isDrawn = false; @Override public void onClick(View v) { // TODO Auto-generated method stub if(!isDrawn) { DrawCanvas mycanvas = (DrawCanvas)findViewById(R.id.SurfaceView01); mycanvas.startDrawImage(); isDrawn = true; } } }; }
As you see above, in the activity, we define a OnClickListener
. Inside we will call our canvas to draw the bitmap. In the DrawCanvas sample, you can find the function startDrawImage()
, and it will start a thread to call back the onDraw()
function, which will draw the real bitmap on the canvas.
How to Fix the Crash Bug
In our customized class
DrawCanvas
, change the function onDraw(Canvas canvas)
as following:
protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub Bitmap sweet = BitmapFactory.decodeResource(getResources(), R.drawable.sq); canvas.drawColor(color.black); canvas.drawBitmap(sweet, 0, 0, null); canvasThread.setRunning(false); }
I finded answers in [url=http://www.google.com.hk]google[/url]
Yeah that’s what I’m tlkiang about baby–nice work!
Good points all aornud. Truly appreciated.
You’ve got it in one. Couldn’t have put it beettr.
Pin my tail and call me a donkey, that really hlpeed.
Respected Sir,
Please give me more suggestion, how to use a dynamic animation in android app.
—
Thanks & Regards,
Ranjeet Kushwaha
7503709347
Hello dude,
I am using the static image in bitmap, now i want to fill the colors into that image. i am able to draw the color in side the image but at stroke points also filling with colors. pleas can u help me in that, i want fill the color only inside not on borders of out line image.
What drawing method are you using? canvas.drawColor will fill the entire canvas with the specified color.
If you want to fill one area, I think you can draw an rectangle for example.
bolshy yarbles for all