How to draw Arcs in Android using canvas?

By | January 10, 2013

This is a simple example showing how to draw Arcs in android, You can use this to create piecharts or someother similar thing you want.

Arc Drawing

Arc Drawing

Arc Drawing

Arc Drawing

Here we have 3 classes.
1. GraphicsActivity.java
2. MainActivity.java
3. PictureLayout.java

GraphicsActivity.java

[java]
package com.coderzheaven.arcdrawing;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;

class GraphicsActivity extends Activity {
// set to true to test Picture
private static final boolean TEST_PICTURE = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}

@Override
public void setContentView(View view) {
if (TEST_PICTURE) {
ViewGroup vg = new PictureLayout(this);
vg.addView(view);
view = vg;
}

super.setContentView(view);
}
}
[/java]

PictureLayout.java

[java]
package com.coderzheaven.arcdrawing;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Picture;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;

public class PictureLayout extends ViewGroup {
private final Picture mPicture = new Picture();

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

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

@Override
public void addView(View child) {
if (getChildCount() > 1) {
throw new IllegalStateException("PictureLayout can host only one direct child");
}

super.addView(child);
}

@Override
public void addView(View child, int index) {
if (getChildCount() > 1) {
throw new IllegalStateException("PictureLayout can host only one direct child");
}

super.addView(child, index);
}

@Override
public void addView(View child, LayoutParams params) {
if (getChildCount() > 1) {
throw new IllegalStateException("PictureLayout can host only one direct child");
}

super.addView(child, params);
}

@Override
public void addView(View child, int index, LayoutParams params) {
if (getChildCount() > 1) {
throw new IllegalStateException("PictureLayout can host only one direct child");
}

super.addView(child, index, params);
}

@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int count = getChildCount();

int maxHeight = 0;
int maxWidth = 0;

for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
measureChild(child, widthMeasureSpec, heightMeasureSpec);
}
}

maxWidth += getPaddingLeft() + getPaddingRight();
maxHeight += getPaddingTop() + getPaddingBottom();

Drawable drawable = getBackground();
if (drawable != null) {
maxHeight = Math.max(maxHeight, drawable.getMinimumHeight());
maxWidth = Math.max(maxWidth, drawable.getMinimumWidth());
}

setMeasuredDimension(resolveSize(maxWidth, widthMeasureSpec),
resolveSize(maxHeight, heightMeasureSpec));
}

private void drawPict(Canvas canvas, int x, int y, int w, int h,
float sx, float sy) {
canvas.save();
canvas.translate(x, y);
canvas.clipRect(0, 0, w, h);
canvas.scale(0.5f, 0.5f);
canvas.scale(sx, sy, w, h);
canvas.drawPicture(mPicture);
canvas.restore();
}

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(mPicture.beginRecording(getWidth(), getHeight()));
mPicture.endRecording();

int x = getWidth()/2;
int y = getHeight()/2;

if (false) {
canvas.drawPicture(mPicture);
} else {
drawPict(canvas, 0, 0, x, y, 1, 1);
drawPict(canvas, x, 0, x, y, -1, 1);
drawPict(canvas, 0, y, x, y, 1, -1);
drawPict(canvas, x, y, x, y, -1, -1);
}
}

@Override
public ViewParent invalidateChildInParent(int[] location, Rect dirty) {
location[0] = getLeft();
location[1] = getTop();
dirty.set(0, 0, getWidth(), getHeight());
return getParent();
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = super.getChildCount();

for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE) {
final int childLeft = getPaddingLeft();
final int childTop = getPaddingTop();
child.layout(childLeft, childTop,
childLeft + child.getMeasuredWidth(),
childTop + child.getMeasuredHeight());

}
}
}
}
[/java]

MainActivity.java
[java]
package com.coderzheaven.arcdrawing;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;

public class MainActivity extends GraphicsActivity implements OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

Button b1 = (Button) findViewById(R.id.button1);
Button b2 = (Button) findViewById(R.id.button2);
Button b3 = (Button) findViewById(R.id.button3);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
}

@Override
public void onClick(View v) {
int id = v.getId();
Style sytle = null;
boolean use_centre = false;
final LinearLayout r1 = (LinearLayout) findViewById(R.id.l1);
if (MainActivity.this.findViewById(1) != null)
r1.removeView(MainActivity.this.findViewById(1));
switch (id) {
case R.id.button1:
use_centre = true;
sytle = Paint.Style.FILL;
break;
case R.id.button2:
use_centre = false;
sytle = Paint.Style.STROKE;
break;
case R.id.button3:
use_centre = true;
sytle = Paint.Style.STROKE;
break;
default:
break;

}
SampleView s = new SampleView(MainActivity.this);
s.setId(1);
s.startDraw(sytle, use_centre);
r1.addView(s);
}

private static class SampleView extends View {
private Paint mPaint;
private Paint mFramePaint;
private RectF mBigOval;
private float mStart;
private float mSweep;
private boolean use_centre = false;
private static final float SWEEP_INC = 0.5f;
private static final float START_INC = 15;

public SampleView(Context context) {
super(context);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(0x880000FF);
mPaint.setStrokeWidth(4);

mBigOval = new RectF(40, 10, 280, 250);

mFramePaint = new Paint();
mFramePaint.setAntiAlias(true);
mFramePaint.setStrokeWidth(4);
}

public void startDraw(Style style, boolean use_centre) {
this.use_centre = use_centre;
mPaint.setStyle(style);
mFramePaint.setStyle(style);
}

private void drawArcs(Canvas canvas, RectF oval, boolean useCenter,
Paint paint) {
// canvas.drawRect(oval, mFramePaint);
canvas.drawArc(oval, mStart, mSweep, useCenter, paint);
}

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);

drawArcs(canvas, mBigOval, use_centre, mPaint);

mSweep += SWEEP_INC;
if (mSweep > 360) {
mSweep -= 360;
mStart += START_INC;
if (mStart >= 360) {
mStart -= 360;
}
}
invalidate();
}
}
}
[/java]

Download the complete source code from here.

2 thoughts on “How to draw Arcs in Android using canvas?

  1. Pingback: android - Come disegnare una linea curva in android?

  2. Pingback: How to draw a curved line in android?

Leave a Reply

Your email address will not be published. Required fields are marked *