Draw beautiful diagram effortlessly on ipad. Click here to know more..

Sunday, January 15, 2012

Drawing and erasing using touch on Android

Drawing/Erasing using touch is a common feature in many mobile phone/tablet based apps. Writing code for this feature is pretty simple for android. Here are steps to do that:
  • add a custom view on which you will draw.
  • process touch event on view.
  • on touch event, record points where touch event occurred.
  • in onDraw method, draw points that were recorded.

Adding a custom view:

We will derive a class from View class for implementing drawing canvas. And we will add this to UI tree. To add this to UITree, create a LinearLayout in which the custom view will be added. The LinearLayout is declared in layout xml as:
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:id="@+id/drawPanel">
    </LinearLayout>
and from the code, add the custom view to this LinearLayout as:
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LinearLayout ll = (LinearLayout)findViewById(R.id.drawPanel);
        DrawPanel drawingPanel = new DrawPanel(getApplicationContext());
        ll.addView(drawingPanel);
    }
This code finds the LinearLayout object which was defined in XML and then adds an object of DrawPanel to this. The DrawPanel is the custom View class which is being used for drawing. Here is the implementation of DrawPanel


public class DrawPanel extends View { 
public DrawPanel(Context context) {
  super(context);
  points = new ArrayList();
  strokes = new ArrayList();
  paint = createPaint(Color.GREEN, 8);
 }

 @Override
 public void onDraw(Canvas c){
  super.onDraw(c);
  this.setBackgroundColor(Color.WHITE);
  for(Object obj: strokes){
   drawStroke((ArrayList)obj, c);
  }
  
  drawStroke(points, c);
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event){
  if(event.getActionMasked() == MotionEvent.ACTION_MOVE){
   points.add(new Point((int)event.getX(), (int)event.getY()));
   invalidate();
  }
  
  if(event.getActionMasked() == MotionEvent.ACTION_UP){
   this.strokes.add(points);
   points = new ArrayList();
  }
  
  return true;
 }
 
 private void drawStroke(ArrayList stroke, Canvas c){
  if (stroke.size() > 0) {
   Point p0 = (Point)stroke.get(0);
   for (int i = 1; i < stroke.size(); i++) {
    Point p1 = (Point)stroke.get(i);
    c.drawLine(p0.x, p0.y, p1.x, p1.y, paint);
    p0 = p1;
   }
  }
 }
 
 private Paint createPaint(int color, float width){
  Paint temp = new Paint();
  temp.setStyle(Paint.Style.STROKE);
  temp.setAntiAlias(true);
  temp.setColor(color);
  temp.setStrokeWidth(width);
  temp.setStrokeCap(Cap.ROUND);
  
  return temp;
 }
 
 private Paint paint;
 private ArrayList points;
 private ArrayList strokes;
}

The above code is for drawing. With a small tweak, erasing can be implemented. While erasing, set the paint color as that of background, that's it!! 

The above code is used in Scratchpad, a drawing app for Android tablets.