Monday, June 8, 2009

Drawing with Canvas in Android

Update - Nov 21, 2010
Created a series over this topic over at Drawing with Canvas Series, more articles would appear in the future :)

Update - Nov 13, 2010
There is a renewed/enchanced version of this tutorial though i still recommend to read this article if you're completely new to Android or Canvas in Android, for we reference back to this article. The updated one is at Drawing with Canvas in Android Renewed

Introduction
If you had been reading previous post then you'll know i'm not a java guy, i literally spend hours trying to figure out how canvas works perfectly on java. Then i remember that javascript/html5 has canvas too, so i revisited this one (haven't visited it for almost half a year) https://developer.mozilla.org/en/drawing_graphics_with_canvas and see that i must use paths (2nd example, beginPath) rather than drawing point by point. So together with this article http://www.droidnova.com/playing-with-graphics-in-android-part-iv,182.html. I come up with a pretty descend drawing app.


To do this:
Copy the whole code from droidnova the replace the following.

On your Activity
private ArrayList _graphics = new ArrayList();
private Paint mPaint;
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(new DrawingPanel(this));
  mPaint = new Paint();
  mPaint.setDither(true);
  mPaint.setColor(0xFFFFFF00);
  mPaint.setStyle(Paint.Style.STROKE);
  mPaint.setStrokeJoin(Paint.Join.ROUND);
  mPaint.setStrokeCap(Paint.Cap.ROUND);
  mPaint.setStrokeWidth(3);
}


On your SurfaceView
@Override
public boolean onTouchEvent(MotionEvent event) {
  synchronized (_thread.getSurfaceHolder()) {
    if(event.getAction() == MotionEvent.ACTION_DOWN){
      path = new Path();
      path.moveTo(event.getX(), event.getY());
      path.lineTo(event.getX(), event.getY());
    }else if(event.getAction() == MotionEvent.ACTION_MOVE){
      path.lineTo(event.getX(), event.getY());
    }else if(event.getAction() == MotionEvent.ACTION_UP){
      path.lineTo(event.getX(), event.getY());
      _graphics.add(path);
    }
    return true;
  }
}
@Override
public void onDraw(Canvas canvas) {
  for (Path path : _graphics) {
    //canvas.drawPoint(graphic.x, graphic.y, mPaint);
    canvas.drawPath(path, mPaint);
  }
}


Explanation
We create a path and start that path when the MotionEvent is down, or when the user first touch the screen, then add a lineTo, the x and y when the user moves his fingers. Then stop and push the path we had build to our array of Paths.
public boolean onTouchEvent(MotionEvent event) { .... }

Then during the draw function we loop through the array and print them on our canvas.
public void onDraw(Canvas canvas) { ... }


References
http://www.droidnova.com/playing-with-graphics-in-android-part-iv,182.html
https://developer.mozilla.org/en/drawing_graphics_with_canvas
Android IRC - irc://freenode/android-dev
Post a Comment