第一部分 自定義PieView
public class PieChartView extends View {
//定義多種顏色供使用
private int arcColos[] = new int[]{getResources().getColor(R.color.gold), getResources().getColor(R.color.greenyellow)
, getResources().getColor(R.color.lightgreen), getResources().getColor(R.color.dodgerblue)
, getResources().getColor(R.color.freshgreen), getResources().getColor(R.color.lightskyblue)};
private final static String TAG = "PieChartView";
private List<PieMember> data = null;
//圓心位置
private int centerX, centerY = 0;
//整個餅圖的半徑
private float radius = 200;
//中間原型半徑
private float hollowRadius = 0;
//餅圖邊距
private float margin = 0;
//餅圖名稱
private String pieName = "";
//lable高度
private int lableHeight = 80;
private float fontSize = 0;
private Paint bgPaint = null;
private Paint arcPaint = null;
private Paint textPaint = null;
public PieChartView(Context context) {
super(context);
this.init();
}
public PieChartView(Context context, AttributeSet attrs) {
super(context, attrs);
this.init();
}
public PieChartView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.init();
}
public void setPieName(String pieName) {
this.pieName = pieName;
postInvalidate();
}
private void init() {
this.bgPaint = new Paint();
bgPaint.setAntiAlias(true);
this.bgPaint.setColor(getResources().getColor(R.color.theme_main_blue));
this.bgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
this.arcPaint = new Paint();
this.arcPaint.setAntiAlias(true);
this.arcPaint.setStyle(Paint.Style.FILL_AND_STROKE);
this.textPaint = new Paint();
this.textPaint.setColor(getResources().getColor(R.color.black_overlay));
this.textPaint.setAntiAlias(true);//去除鋸齒
this.textPaint.setFilterBitmap(true);//對位圖進行濾波處理
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//設置整個空間的背景一般情況下注銷即可
//canvas.drawColor(getResources().getColor(R.color.white));
if (margin == 0) {
margin = getWidth() * 0.05f;
}
if (radius == 0) {
if ((getHeight() - lableHeight) < getWidth()) {
radius = (getHeight() - lableHeight - (margin * 2)) / 2;
} else {
radius = (getWidth() - (margin * 2)) / 2;
}
} else if ((radius * 2) > (getWidth() - (margin * 2))) {
radius = (getWidth() - (margin * 2)) / 2;
} else if ((radius * 2 + lableHeight) > (getHeight() - (margin * 2))) {
ViewGroup.LayoutParams params = getLayoutParams();
params.height = (int) (radius * 2d + lableHeight + (margin * 2d));
setLayoutParams(params);
}
if (hollowRadius == 0) {
hollowRadius = (int) (radius);
}
if (this.centerX == 0) {
this.centerX = getWidth() / 2;
}
if (this.centerY == 0) {
this.centerY = ((getHeight() - lableHeight) / 2)+30;
}
this.fontSize = -scalaFonts((int) (hollowRadius / this.pieName.length() * 0.6f) * 2);
//繪製整個餅圖的底部背景圓
this.bgPaint.setColor(getResources().getColor(R.color.white));
this.bgPaint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(centerX, centerY, radius, bgPaint);
//畫百分比圓弧
this.drawArc(canvas);
canvas.restore();
}
public void drawArc(Canvas canvas) {
RectF rect = new RectF();
rect.left = centerX - radius;
rect.top = centerY - radius;
rect.right = centerX + radius;
rect.bottom = centerY + radius;
RectF rectText = new RectF();
rectText.left = centerX - (radius - (radius * 0.4f));
rectText.top = centerY - (radius - (radius * 0.4f));
rectText.right = centerX + (radius - (radius * 0.4f));
rectText.bottom = centerY + (radius - (radius * 0.4f));
if (this.data == null || this.data.isEmpty()) {
Log.w(TAG, "沒有可以繪製的數據");
arcPaint.setColor(arcColos[0]);
canvas.drawArc(rect, //弧線所使用的矩形區域大小
0, //開始角度
60, //掃過的角度
true, //是否使用中心
arcPaint);
return;
}
int total = 0;//總數
for (PieMember member : data) {
total += member.getNumber();
}
float angle = 0f;
int i = 0;
for (int pointer = 0; pointer < data.size(); pointer++) {
PieMember member = data.get(pointer);
if (member.getColor() == 0) {
if (i >= arcColos.length) {
i = 0;
}
member.setColor(arcColos[i++]);
}
float d = 360f * ((float) member.getNumber() / (float) total);
arcPaint.setColor(member.getColor());
canvas.drawArc(rect, angle, d, true, arcPaint); //根據進度畫圓弧
Path path = new Path();
path.addArc(rectText, angle, d);
Paint citePaint = new Paint();
citePaint.setTextSize(fontSize*10);
citePaint.setStrokeWidth(1);
citePaint.setColor(getResources().getColor(R.color.theme_main_blue));
//繪製餅圖中的文字
canvas.drawTextOnPath(member.getText(), path, 20, 0, citePaint);
//在餅圖的下方繪製文字
// citePaint.setTextSize(fontSize*5);
// float x = getWidth() / data.size() * pointer + margin;
// float y = getHeight() - margin;
// float h = getFontHeight(this.textPaint) * 0.6f;
// canvas.drawText(member.getText() + ":" + member.getNumber(), x + h + (h * 0.3f), y, citePaint);
// //繪製餅圖下方的小方塊
// RectF r = new RectF(x, y - h, x + h, y);
// canvas.drawRect(r, arcPaint);
angle += d;
}
}
/**
* 根據屏幕係數比例獲取文字大小
*
* @return
*/
private static float scalaFonts(int size) {
//暫未實現
return size;
}
/**
* @return 返回指定筆和指定字符串的長度
*/
public static float getFontlength(Paint paint, String str) {
return paint.measureText(str);
}
/**
* @return 返回指定筆的文字高度
*/
public static float getFontHeight(Paint paint) {
Paint.FontMetrics fm = paint.getFontMetrics();
return fm.descent - fm.ascent;
}
/**
* @return 返回指定筆離文字頂部的基準距離
*/
public static float getFontLeading(Paint paint) {
Paint.FontMetrics fm = paint.getFontMetrics();
return fm.leading - fm.ascent;
}
public void setData(List<PieMember> data) {
this.data = data;
postInvalidate();
}
public static class PieMember {
private String text = "";
private int number = 0;
private int color = 0;
public void augment(int n) {
this.number += n;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
}
}
第二部分 color文件
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
//餅圖顏色
<color name="gold">#FFD700</color>
<!-- 金 -->
<color name="greenyellow">#ADFF2F</color>
<!-- 赭 -->
<color name="lightgreen">#90EE90</color>
<!-- 亮綠 -->
<color name="dodgerblue">#1E90FF</color>
<!-- 閃藍 -->
<color name="freshgreen">#C4EAA2</color>
<!-- 清新綠 -->
<color name="lightskyblue">#87CEFA</color>
<!-- 亮天藍 -->
<color name="white">#ffffff</color>
<!-- 白色 -->
<color name="theme_main_blue">#ff20bdea</color>
<color name="black_overlay">#66000000</color>
</resources>
第三部分 Activity中
public class MainActivity extends Activity {
private PieChartView mPieView;
private ArrayList<PieChartView.PieMember> datas = new ArrayList<PieChartView.PieMember>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mPieView = (PieChartView) findViewById(R.id.piechart);
PieChartView.PieMember member1 = new PieChartView.PieMember();
member1.setColor(Color.parseColor("#fcb333"));
member1.setNumber(15);
member1.setText("美女");
PieChartView.PieMember member2 = new PieChartView.PieMember();
member2.setColor(Color.parseColor("#fedd95"));
member2.setNumber(35);
member2.setText("帥哥");
PieChartView.PieMember member3 = new PieChartView.PieMember();
member3.setColor(Color.parseColor("#cccccc"));
member3.setNumber(50);
member3.setText("中性人");
datas.add(member1);
datas.add(member2);
datas.add(member3);
mPieView.setData(datas);
}
}
第四部分 佈局部分
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.liying.viewpager.PieChartView
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_centerHorizontal="true"
android:id="@+id/piechart"
android:layout_marginTop="50dp"
/>
</RelativeLayout>