Apr 30, 2012

Detect TouchEvent on custom View to free draw path dynamically

Override onTouchEvent() method of custom View, to create path dynamically.
Detect TouchEvent on custom View to free draw path dynamically

Create a new class MyView extends View, MyView.java.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class MyView extends View {
 
 boolean freeTouched = false;
 Path freePath;

 public MyView(Context context) {
  super(context);
 }

 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 public MyView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  Paint paint = new Paint();
  paint.setStyle(Paint.Style.STROKE);
  paint.setColor(Color.WHITE);
  paint.setStrokeWidth(3);
  
  if(freeTouched){
   canvas.drawPath(freePath, paint);
  }

 }

 @Override
 public boolean onTouchEvent(MotionEvent event) {
  
  switch(event.getAction()){
  case MotionEvent.ACTION_UP:
   freeTouched = false;
   break;
  case MotionEvent.ACTION_DOWN:
   freeTouched = true;
   freePath = new Path();
   freePath.moveTo(event.getX(), event.getY());
   break;
  case MotionEvent.ACTION_MOVE:
   freePath.lineTo(event.getX(), event.getY());
   invalidate();
   break;
  }
  
  return true;
 }

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }
}


Next:
- Get the canvas bitmap of custom View


Apr 29, 2012

Draw text along path

To draw text along path, we can call Canvas.drawTextOnPath(text, path, hOffset, vOffset, paint).

Draw text along path

Example:
Create a new class MyView extends View. Override the onDraw(Canvas canvas) method calling Canvas.drawTextOnPath() to draw text along path.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

 public MyView(Context context) {
  super(context);
 }

 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }

 public MyView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  Paint paint = new Paint();
  paint.setStyle(Paint.Style.STROKE);
  paint.setColor(Color.WHITE);
  paint.setStrokeWidth(3);
  
  Path path = new Path();
  path.moveTo(50, 50);
  path.cubicTo(500, 100, 100, 500, 1000, 500);
  canvas.drawPath(path, paint);
  canvas.drawPath(path, paint);
  
  paint.setStyle(Paint.Style.FILL_AND_STROKE);
  paint.setTextSize(100);
  
  //drawTextOnPath(text, path, hOffset, vOffset, paint)
  paint.setColor(Color.GRAY);
  canvas.drawTextOnPath("--- Android.Coding ---", path, 110, 5, paint);
  paint.setColor(Color.GREEN);
  canvas.drawTextOnPath("--- Android.Coding ---", path, 100, 0, paint);
 }

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyView(this));
    }
}


Apr 16, 2012

Draw rotated oval, canvas.drawOval + canvas.rotate

Refer to last article Draw oval on canvas, canvas.drawOval(), we can draw oval vertically or horizontally. So, how can we draw a rotated oval? We can rotate the canvas before canvas.drawOval(), and rotate reversely after draw.

Draw rotated oval, canvas.drawOval + canvas.rotate

Example:
Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw oval on Canvas.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

public MyView(Context context) {
super(context);
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(0, 0, getWidth(), getHeight());
canvas.drawOval(oval1, paint);

float rotate_center_x = 200;
float rotate_center_y = 200;
float rotate_angle = 20;

//Draw a oval without rotate
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.BLUE);
RectF oval2 = new RectF(rotate_center_x-150, rotate_center_y-50, rotate_center_x+150, rotate_center_y+50);
canvas.drawOval(oval2, paint);

//Draw a oval on a rotated canvas
canvas.rotate(-rotate_angle, rotate_center_x, rotate_center_y);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
RectF oval3 = new RectF(rotate_center_x-150, rotate_center_y-50, rotate_center_x+150, rotate_center_y+50);
canvas.drawOval(oval3, paint);
//resume original angle
canvas.rotate(rotate_angle, rotate_center_x, rotate_center_y);


paint.setColor(Color.BLUE);
RectF oval4 = new RectF(250, 250, 350, 600);
canvas.drawOval(oval4, paint);
}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}

Apr 13, 2012

Draw oval on canvas, canvas.drawOval()

Draw oval on canvas, canvas.drawOval()

Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw oval on Canvas.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

public MyView(Context context) {
super(context);
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
RectF oval1 = new RectF(0, 0, getWidth(), getHeight());
canvas.drawOval(oval1, paint);

paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
RectF oval2 = new RectF(50, 50, 150, 150);
canvas.drawOval(oval2, paint);

paint.setColor(Color.BLUE);
RectF oval3 = new RectF(250, 50, 350, 400);
canvas.drawOval(oval3, paint);
}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}


Next:
- Draw rotated oval, canvas.drawOval + canvas.rotate



Apr 12, 2012

Detect Touch Event part IV - get touch area

Previous article: Detect Touch Event part III - get touch pressure and size

The method getTouchMajor() and getTouchMinor() (getTouchMajor(int pointerIndex) and getTouchMinor(int pointerIndex) for multi-touch) of MotionEvent returns the length of the major and minor axis of an ellipse that describes the touch area.

Example:

get touch area

package com.TestSingleTouch;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TestSingleTouch extends Activity {

public class TouchView extends View {

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private float x, y;
private float touchMajor, touchMinor;
boolean touching = false;

float pressure = 0; //Touch pressure
float size = 0; //Touch size
final static float PRESET_PRESSURE = 0xFF;
final static float PRESET_SIZE = 300;

public TouchView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
if(touching){

paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(1);

paint.setColor(Color.WHITE);
RectF ovalTouch = new RectF(x-touchMajor/2, y-touchMinor/2, x+touchMajor/2, y+touchMinor/2);

canvas.drawOval(ovalTouch, paint);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// TODO Auto-generated method stub
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),
MeasureSpec.getSize(heightMeasureSpec));
}

@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub

pressure = event.getPressure();
if(pressure > 1){
pressure = 1;
}

size =event.getSize();

String act;

int action = event.getAction();

switch(action){
case MotionEvent.ACTION_MOVE:
act = "ACTION_MOVE\n";
x = event.getX();
y = event.getY();
touchMajor = event.getTouchMajor();
touchMinor = event.getTouchMinor();
touching = true;
break;
case MotionEvent.ACTION_DOWN:
act = "ACTION_DOWN\n";
x = event.getX();
y = event.getY();
touchMajor = event.getTouchMajor();
touchMinor = event.getTouchMinor();
touching = true;
break;
case MotionEvent.ACTION_UP:
act = "ACTION_UP\n";
touching = false;
break;
default:
act = "XXX\n";
touching = false;
}

act += event.toString();
textView.setText(act);

invalidate();
return true;
}
}

TextView textView;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(new TouchView(this));
textView = new TextView(this);
textView.setText("Waiting");
TouchView touchView = new TouchView(this);
LinearLayout mainScreen = new LinearLayout(this);
mainScreen.setOrientation(LinearLayout.VERTICAL);
mainScreen.addView(textView);
mainScreen.addView(touchView);
setContentView(mainScreen);
}
}


Draw cubic bezier on path - cubicTo()

cubicTo (float x1, float y1, float x2, float y2, float x3, float y3)
Add a cubic bezier from the last point, approaching control points (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been made for this contour, the first point is automatically set to (0,0).

Draw cubic bezier on path - cubicTo()

Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw a path with cubicTo().
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();

paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);


path = new Path();
paint.setColor(Color.RED);
paint.setStrokeWidth(3);
path.moveTo(50, 50);
path.cubicTo(300, 50, 100, 400, 400, 400);
canvas.drawPath(path, paint);

path.reset();
paint.setColor(Color.GRAY);
paint.setStrokeWidth(1);
path.moveTo(50, 50);
path.lineTo(300, 50);
path.lineTo(100, 400);
path.lineTo(400, 400);

canvas.drawPath(path, paint);

}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}


Apr 11, 2012

Draw round-rect on canvas, drawRoundRect()

drawRoundRect (RectF rect, float rx, float ry, Paint paint)
Draw the specified round-rect using the specified paint. The roundrect will be filled or framed based on the Style in the paint.
  • rect - The rectangular bounds of the roundRect to be drawn
  • rx - The x-radius of the oval used to round the corners
  • ry - The y-radius of the oval used to round the corners
  • paint - The paint used to draw the roundRect


Draw round-rect on canvas, drawRoundRect()

Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw round-rect on Canvas.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

final RectF rect = new RectF();
paint.setStyle(Paint.Style.STROKE);

rect.set(50, 50, 150, 150);
canvas.drawRoundRect(rect, 10, 10, paint);

rect.set(200, 150, 450, 350);
canvas.drawRoundRect(rect, 30, 30, paint);

paint.setStyle(Paint.Style.FILL);
rect.set(200, 400, 450, 600);
canvas.drawRoundRect(rect, 50, 100, paint);

}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}

Apr 10, 2012

Draw arc on canvas, canvas.drawArc()

To drawa arc on canvas, call canvas.drawArc():
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)

where:
  • oval - The bounds of oval used to define the shape and size of the arc
  • startAngle - Starting angle (in degrees) where the arc begins
  • sweepAngle - Sweep angle (in degrees) measured clockwise
  • useCenter - If true, include the center of the oval in the arc, and close it if it is being stroked. This will draw a wedge
  • paint - The paint used to draw the arc


Draw arc on canvas, canvas.drawArc()

Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw arc on Canvas.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(1);
paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

final RectF oval = new RectF();
paint.setStyle(Paint.Style.STROKE);
/*
* drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
*
* oval - The bounds of oval used to define the shape and size of the arc
* startAngle - Starting angle (in degrees) where the arc begins
* sweepAngle - Sweep angle (in degrees) measured clockwise
* useCenter - If true, include the center of the oval in the arc, and close it if it is being stroked. This will draw a wedge
* paint - The paint used to draw the arc
*/
oval.set(50, 50, 150, 150);
canvas.drawArc(oval, 0, 45, true, paint);

oval.set(200, 150, 450, 350);
canvas.drawArc(oval, 0, 270, true, paint);

oval.set(200, 400, 450, 600);
canvas.drawArc(oval, 0, 270, false, paint);


}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}

Apr 8, 2012

Draw circle on canvas, canvas.drawCircle()

Draw circle on canvas, canvas.drawCirclet()

Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw circle on Canvas.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(50, 50, 30, paint);

paint.setStyle(Paint.Style.FILL);
canvas.drawCircle(300, 300, 200, paint);
//drawCircle(cx, cy, radius, paint)

}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}

Apr 6, 2012

Draw rectangle on canvas, canvas.drawRect()

Draw rectangle on canvas, canvas.drawRect()


Create a new class MyView extends View. Override the onDraw(Canvas canvas) method to draw rectangle on Canvas.

package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

canvas.drawRect(30, 50, 200, 350, paint);
canvas.drawRect(100, 100, 300, 400, paint);
//drawRect(left, top, right, bottom, paint)

}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}

Apr 5, 2012

Draw on Canvas directly, in custom View.

Draw on Canvas directly, in custom View.

Create a new class MyView extends View, it's our custom View. Override the onDraw(Canvas canvas) method to draw on Canvas directly.
package com.AndroidMyCanvas;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

Paint paint;
Path path;

public MyView(Context context) {
super(context);
init();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public MyView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}

private void init(){
paint = new Paint();
paint.setColor(Color.BLUE);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);

path = new Path();
path.moveTo(50, 50);
path.lineTo(50, 500);
path.lineTo(200, 500);
path.lineTo(200, 300);
path.lineTo(350, 300);

canvas.drawPath(path, paint);

}

}


Modify main Java activity to setContentView() using our custom View, MyView.
package com.AndroidMyCanvas;

import android.app.Activity;
import android.os.Bundle;

public class AndroidMyCanvasActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
}
}


Infolinks In Text Ads