上一章我们学习了自定义View的基础用法,但是还没有实际运用上去,这次我们将绘制一个目前比较常见的饼图压压惊。
效果预览图:
以下的代码都有详细的注释就直接开撸了。
1.创建实体类_存储数据
public class PieData {
//用户关心的数据
public String name; //名字
public float value; //数据
public float percentage;//百分比
public int color; //颜色
//非用户关心的数据
public float angle; //角度
public PieData(@NonNull String name, @NonNull float value) {
this.name = name;
this.value = value;
}
}
创建饼图View:
public class PieView extends View {
//饼状图初始化绘制角度
private float mStartAngle = 0;
//数据集合
private List<PieData> mPieDatas;
// 颜色表
private int[] VORDIPLOM_COLORS;
//宽高
private int mWidth, mHeight;
//画笔
private Paint mPaint = new Paint();
public PieView(Context context) {
this(context, null);
}
public PieView(Context context, AttributeSet attrs) {
super(context, attrs);
initPaint();
}
/**
* 初始化画笔
*/
private void initPaint() {
//设置画笔为填充模式
mPaint.setStyle(Paint.Style.FILL);
//抗锯齿
mPaint.setAntiAlias(true);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mWidth = w;
mHeight = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//判断数据不为空
if (null == mPieDatas) return;
//当前起始角度
float currentStartAngle = mStartAngle;
//将画布坐标原点移动到中心位置
canvas.translate(mWidth / 2, mHeight / 2);
//饼状图的半径
float radii = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);
//饼状图绘制的区域-中心区域-参数(形状和大小)
RectF rectF = new RectF(-radii, -radii, radii, radii);
//绘制圆弧
for (int i = 0; i < mPieDatas.size(); i++) {
PieData pieData = mPieDatas.get(i);
//画笔设置颜色
mPaint.setColor(pieData.color);
//绘制圆弧
canvas.drawArc(rectF, currentStartAngle, pieData.angle, true, mPaint);
//设置角度
currentStartAngle += pieData.angle;
}
}
/**
* 设置起始角度
*/
public void setStartAngle(int mStartAngle) {
this.mStartAngle = mStartAngle;
//刷新
invalidate();
}
/**
* 设置数据
*/
public void setData(List<PieData> mPieDatas, int[] VORDIPLOM_COLORS) {
this.mPieDatas = mPieDatas;
this.VORDIPLOM_COLORS = VORDIPLOM_COLORS;
//初始化数据
initData(mPieDatas);
//刷新
invalidate();
}
/**
* 初始化数据
*/
private void initData(List<PieData> mPieDatas) {
//判断数据不为空
if (null == mPieDatas || mPieDatas.size() == 0) return;
//用来做百分比的底数
int sumValue = 0;
for (int i = 0; i < mPieDatas.size(); i++) {
PieData pieData = mPieDatas.get(i);
//计算数值和
sumValue += pieData.value;
//设置颜色
pieData.color = VORDIPLOM_COLORS[i];
}
for (int i = 0; i < mPieDatas.size(); i++) {
PieData pieData = mPieDatas.get(i);
//百分比
float percentage = pieData.value / sumValue;
//对应的角度
float angle = percentage * 360;
//记录百分比大小
pieData.percentage = percentage;
//记录角度大小
pieData.angle = angle;
//
}
}
}
3.设置数据并展示
public class MainActivity extends AppCompatActivity {
// 颜色表
private static final int[] VORDIPLOM_COLORS = {
Color.rgb(192, 255, 140), Color.rgb(255, 247, 140), Color.rgb(255, 208, 140),
Color.rgb(140, 234, 255), Color.rgb(255, 140, 157)
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//在Activity中
PieView customView = new PieView(this);
setContentView(customView);
//添加饼图数据
List<PieData> datas = new ArrayList<>();
PieData pieData = new PieData("zmj", 60);
PieData pieData2 = new PieData("zmj", 30);
PieData pieData3 = new PieData("zmj", 40);
PieData pieData4 = new PieData("zmj", 20);
PieData pieData5 = new PieData("zmj", 20);
datas.add(pieData);
datas.add(pieData2);
datas.add(pieData3);
datas.add(pieData4);
datas.add(pieData5);
//设置饼图数据和颜色表
customView.setData(datas, VORDIPLOM_COLORS);
}
}
源码下载
end:
最后推荐一个图表类框架提供学习:https://github.com/PhilJay/MPAndroidChart