首先我们需要定义个数据类来放置需要的参数,然后我们就需要确定我们需要那些参数!
/**
* Created by ML on 2016/12/29.
* 饼图统计图
*/
public class PieData {
//用户关心
private String pieName; // 名字
private float value; // 数值
private float percentage; //百分比
//用户不关心
private int pieColor = 0; //颜色
private float pieAngle = 0; //角度
public PieData(@NonNull String pieName,@NonNull float value) {
this.pieName = pieName;
this.value = value;
}
public String getPieName() {
return pieName;
}
public void setPieName(String pieName) {
this.pieName = pieName;
}
public float getValue() {
return value;
}
public void setValue(float value) {
this.value = value;
}
public float getPercentage() {
return percentage;
}
public void setPercentage(float percentage) {
this.percentage = percentage;
}
public int getPieColor() {
return pieColor;
}
public void setPieColor(int pieColor) {
this.pieColor = pieColor;
}
public float getPieAngle() {
return pieAngle;
}
public void setPieAngle(float pieAngle) {
this.pieAngle = pieAngle;
}
之后就是自定义View绘制图形了:
/**
* Created by ML on 2016/12/29.
*/
public class PieView extends View {
private Paint mPaint;
// 颜色表(注意: 此处定义颜色使用的是ARGB,带Alpha通道的)
private int[] mColors = {0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080,
0xFFE6B800, 0xFF7CFC00};
private ArrayList<PieData> mPieDatas = new ArrayList<>();
private float startAngle = 0; //绘制扇形开始角度
private int viewWidth;
private int viewHight;
/**
* 构造方法
*
* @param context
*/
public PieView(Context context) {
this(context, null);
}
public PieView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
public void initPaint() {
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(10);
mPaint.setAntiAlias(true); //防止边缘锯齿!
}
/**
* 测量View的大小
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 确定View的大小
*
* @param w
* @param h
* @param oldw
* @param oldh
*/
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;
viewHight = h;
}
/**
* 确定子View的布局
*
* @param changed
* @param left
* @param top
* @param right
* @param bottom
*/
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
public void setStartAngle(float startAngle) {
this.startAngle = startAngle;
invalidate();
}
public void setPieDatas(ArrayList<PieData> pieDatas) {
this.mPieDatas = pieDatas;
initData(mPieDatas);
invalidate();
}
private void initData(ArrayList<PieData> pieDatas) {
if (pieDatas == null || pieDatas.size() == 0) {
return;
}
float allValue = 0;
float allAngle = 0;
for (int i = 0; i < pieDatas.size(); i++) {
PieData data = pieDatas.get(i);
allValue += data.getValue();
int j = i % mColors.length;
data.setPieColor(mColors[j]);
}
for (int i = 0; i < pieDatas.size(); i++) {
PieData data = pieDatas.get(i);
float percentage = data.getValue() / allValue;
float angle = percentage * 360;
data.setPieAngle(angle);
data.setPercentage(percentage);
allAngle += angle;
Log.i("angle", "" + data.getPieAngle());
}
Log.e("allAngle", allAngle + "");
}
/**
* 绘制图形
*
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mPieDatas == null || mPieDatas.size() == 0) {
return;
}
float currentStartAngle = startAngle;
canvas.translate(viewWidth / 2, viewHight / 2); //将画布的坐标原点移动到中心位置!
float r = (float) (Math.min(viewWidth, viewHight) / 2 * 0.8); //饼状图的半径
RectF rect = new RectF(-r, -r, r, r); //根据半径得到矩形
for (PieData data : mPieDatas) { //循环绘制扇形饼图
mPaint.setColor(data.getPieColor());
canvas.drawArc(rect, currentStartAngle, data.getPieAngle(), true, mPaint);
currentStartAngle += data.getPieAngle();
}
}
/*对外提供设置数据接口*/
上面已经注释了一些关键的地方,剩下的都是挺简单的逻辑问题就不多说了,最后就是在布局中使用或者在代码中使用都可以!
public class MainActivity extends AppCompatActivity {
private ArrayList<PieData> mPieDatas = new ArrayList<>();
private PieView mPieView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final PieView view = new PieView(this);
setContentView(R.layout.activity_main);
initData();
mPieView = (PieView) findViewById(R.id.pieView);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mPieView.setPieDatas(mPieDatas);
}
}, 50);
}
private void initData() {
mPieDatas.add(new PieData("土建一部", 100));
mPieDatas.add(new PieData("土建二部", 200));
mPieDatas.add(new PieData("土建三部", 300));
mPieDatas.add(new PieData("安装一部", 400));
mPieDatas.add(new PieData("安装二部", 500));
mPieDatas.add(new PieData("市政工程部", 600));
mPieDatas.add(new PieData("招标代理部", 700));
}
}
或者:
com.example.a20161005.custormview.PieChartView.PieView
android:id=”@+id/pieView”
android:layout_width=”match_parent”
android:layout_height=”match_parent”
/>