【Android】アニメーション付き円グラフを作ってみる

More than 3 years have passed since last update.



http://qiita.com/kitanoow/items/91c6031ab903523b8cd7

http://qiita.com/kitanoow/items/bfd963ed9bf6f8f708ed

この辺に引き続き。

ただし中切り抜きは出来ず(どうにか方法はありそうですが、いい方法が思い浮かばず)

半径は対象表示領域の約半分として調整

アニメーションといっても実質はタイマーで管理し、描画部分を

徐々に増やしているだけ。


PieGraphView.java


public class PieGraphView extends View {
private ArrayList<HashMap<String,String>> params;
float _end_angle = -90;

public PieGraphView(Context context, ArrayList<HashMap<String, String>> params) {
super(context);
this.params = params;

}

public void onDraw(Canvas c){
int width = c.getWidth();
int length = params.size();
float max = 0;
for(int i=0;i<length;i++) {
float val = Integer.parseInt(params.get(i).get("value"));
max += val;
}
float radius = width/2 - 30;
float start_angle = -90;
float end_angle = 0;
GraphPoint center = new GraphPoint(radius + 15, radius + 15 );
for(int i=0;i<length;i++) {
float val = Integer.parseInt(params.get(i).get("value"));
end_angle = start_angle + 360 * (val / max);
if(end_angle > _end_angle) {
end_angle = _end_angle;
}
this.createPieSlice(c,Integer.parseInt(params.get(i).get("color")),start_angle,end_angle,center,radius);
start_angle = end_angle;
}
}

private void createPieSlice(Canvas c, int color,float start_angle,float end_angle,GraphPoint center,float r){
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setColor(color);
RectF oval1 = new RectF(center.getX()-r, center.getY()-r, center.getX() + r, center.getY() + r);
c.drawArc(oval1, start_angle, end_angle - start_angle, true, paint);

//外枠
paint = new Paint();
paint.setColor(Color.argb(255, 0, 0, 0));
paint.setStyle(Paint.Style.STROKE);
c.drawArc(oval1, start_angle, end_angle-start_angle, true, paint);

}

Timer timer;

public void startAnimation(){
_end_angle = -90;
final Handler handler = new Handler();
TimerTask task = new TimerTask() {
@Override
public void run() {
float angle = (float)(360 / 100.0);
_end_angle += angle;
if(_end_angle > 270) {
_end_angle = 270;
timer.cancel();
}
handler.post(new Runnable() {
@Override
public void run() {
invalidate();
}
});
}
};

timer = new Timer();
//アニメーションのスピード調整できるようにしたいところ
timer.schedule(task,0,30);

}
public void changeParam(ArrayList<HashMap<String,String>> params)
{
this.params = params;
this.invalidate();
}

}


x,y管理用。いらんかったかも。


GraphPoint.java


public class GraphPoint {
private float x;
private float y;
public GraphPoint(float x, float y) {
this.x = x;
this.y = y;
}

public float getX() {
return x;
}

public float getY() {
return y;
}

public void setX(float x) {
this.x = x;
}

public void setY(float y) {
this.y = y;
}

}


利用イメージはこんな感じで。

1秒後にアニメーションを開始させている


MainActivity.java

public class MainActivity extends ActionBarActivity {
protected PieGraphView pieGraphView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//activity_main.xmlで用意した、ただのFrameLayout
FrameLayout circle = (FrameLayout)findViewById(R.id.circleView);
circle.setBackgroundColor(Color.argb(0, 0, 0, 0));

ArrayList<HashMap<String,String>> params = new ArrayList<HashMap<String,String>>();
ArrayList<Integer> color = new ArrayList<Integer>();
color.add(Color.argb(255,255,0,0));
color.add(Color.argb(255,0,255,0));
color.add(Color.argb(255,0,0,255));
color.add(Color.argb(255,255,255,0));

Random rnd = new Random();
for(int i=0;i<4;i++){
HashMap<String,String> map = new HashMap<String,String>();
int r = rnd.nextInt(100) + 1;
map.put("color", String.valueOf(color.get(i)));
map.put("value", String.valueOf(r));
params.add(map);
}
pieGraphView = new PieGraphView(this,params);
circle.addView(pieGraphView);

new Handler().postDelayed(new Runnable() {
@Override
public void run() {
pieGraphView.startAnimation();
}
},1000);
}

}