繪製一個順序添加的餅狀圖(備註:順時針添加)
首先先上效果圖
下面是相關的實體類
public class MyPieData {
private float value; //傳進來的數值
private float angle; //當前數值對應角度
private int color; //畫筆顏色
private float percentage;
private String name;
public MyPieData( String name,float value) {
this.value = value;
this.name = name;
}
public float getPercentage() {
return percentage;
}
public void setPercentage(float percentage) {
this.percentage = percentage;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public float getAngle() {
return angle;
}
public void setAngle(float angle) {
this.angle = angle;
}
public float getValue() {
return value;
}
public void setValue(float value) {
this.value = value;
}
}
然後是自定義View代碼
public class MyPieChart extends View {
private int[] mColors = {0xFFFF0000, 0xFFF7C709, 0xFFF7F709, 0xFF97F709, 0xFF22DDB8,0xFF1A94E6,0xFF4D2BD5,0xCC00FF};
private Paint paint;
private Paint textPaint;
private int width,height;
private float resetStartAngle;
private RectF rect;//弧形的繪製區域
private List<MyPieData>list;
private int size;
private int myPieNum;
private float r;
private Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (myPieNum<size){
myPieNum++;
invalidate();
sendEmptyMessageDelayed(0,50*myPieNum);
}
}
};
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
width=w;
height=h;
r= (float) (Math.min(width,height)/2*0.6);
rect=new RectF(-r,-r,r,r);
}
public MyPieChart(Context context) {
this(context,null);
}
public MyPieChart(Context context, AttributeSet attrs) {
super(context, attrs);
paint=new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
textPaint=new Paint();
textPaint.setAntiAlias(true);
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(16);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(width/2,height/2);
int count=0;
float startAngle=resetStartAngle;
float sweepAngle;
if (list!=null){
while (count<myPieNum){
MyPieData myPieData=list.get(count);
sweepAngle=myPieData.getAngle();
paint.setColor(myPieData.getColor());
canvas.drawArc(rect,startAngle,sweepAngle,true,paint);
String text=myPieData.getName()+"="+myPieData.getPercentage()+"%";
//將文字繪製在弧形的中點,所以sweepAngle/2
float x=(float)Math.cos((sweepAngle/2+startAngle)/360*2*Math.PI)*(r+20);
float y=(float)Math.sin((sweepAngle/2+startAngle)/360*2*Math.PI)*(r+20);
canvas.drawText(text,x,y,textPaint);
startAngle+=sweepAngle;
count++;
}
}
}
public void setStartAngle(float startAngle){
resetStartAngle=startAngle;
}
public void setData(List<MyPieData> list){
this.list=list;
initData();
myPieNum=1;
invalidate();
handler.sendEmptyMessageDelayed(0,50);
}
private void initData() {
size=list.size();
float count=0;
for (int i=0;i<size;i++){
MyPieData myPieData=list.get(i);
count+=myPieData.getValue();
}
for (int i=0;i<size;i++){
MyPieData myPieData=list.get(i);
float percentage= myPieData.getValue()/count;
float angle=360*percentage;
myPieData.setAngle(angle);
myPieData.setColor(mColors[i]);
DecimalFormat fmt=new DecimalFormat("0.##");//建立一個輸出格式最多爲小數點後兩位的模板
myPieData.setPercentage(Float.valueOf(fmt.format(percentage)));
}
}
}
在佈局中引用
<com.example.mytestapplication.widget.MyPieChart
android:id="@+id/myPidChart"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
給MyPieChart添加數據
MyPieChart myPieChart=(MyPieChart)findViewById(R.id.myPidChart);
myPieChart.setStartAngle(30);
List<MyPieData>list=new LinkedList<>();
MyPieData myPieData=new MyPieData("a",10);
list.add(myPieData);
myPieData=new MyPieData("b",20);
list.add(myPieData);
myPieData=new MyPieData("c",30);
list.add(myPieData);
myPieData=new MyPieData("d",10);
list.add(myPieData);
myPieData=new MyPieData("e",20);
list.add(myPieData);
myPieData=new MyPieData("f",35);
list.add(myPieData);
myPieData=new MyPieData("g",15);
list.add(myPieData);
myPieChart.setData(list);
大功告成