1.概述
最近公司要让做一个类似仪表盘样式的View,也学习了一些,来记录一下实现步骤。
2.效果
1.仪表盘

2.饼图

3.实现思路
3.1.仪表盘实现思路
1.首先画一个圆弧,定义圆心,起始角度,扫过的角度。
2.绘制圆弧上的每一个刻度。使用PathEffect,他的其中一个子类PathDashPathEffect来设置(细节一会代码详细指名)
3.绘制最后的指针
3.2.饼图实现思路
1.绘制圆弧,分别设置每一个圆弧的角度。和颜色。
2.单独处理第二块突出的圆弧。绘制该块圆弧时,我们先将画布平移。再进行绘制
4.代码实现
4.1.仪表盘
/**
* 仪表盘
*/
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class DashBoard extends View {
private Paint mPaint;
private Path mPath;
private PathDashPathEffect effect;
private static final float angle = 120;
private static final float radius = UIUtils.dp2px(150);
public DashBoard(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
//执行在super之后
{
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeWidth(UIUtils.dp2px(2));
mPaint.setStyle(Paint.Style.STROKE);
mPath = new Path();
mPath.addRect(0,0,UIUtils.dp2px(2),UIUtils.dp2px(10), Path.Direction.CW); //添加一个矩形
Path arg = new Path();
arg.addArc(getWidth() / 2 - radius,getHeight() / 2 - radius,getWidth() / 2 + radius,getHeight() / 2 + radius,90 + angle / 2,360 - angle);
PathMeasure measure = new PathMeasure(arg,false); //获取圆弧长度, 绘制20个刻度,先减去一个刻度的宽度在除以20
/**
* advance:每一个刻度之间的距离
* phase:起始的刻度需要空出的距离
*/
effect = new PathDashPathEffect(mPath, (measure.getLength() - UIUtils.dp2px(2)) / 20,0, PathDashPathEffect.Style.ROTATE);
// mPaint.setPathEffect(new PathDashPathEffect(mPath,50,0, PathDashPathEffect.Style.ROTATE));
}
/**
* 该方法调用是在onLayout之后,如果实际尺寸改变了他会调用一次,否则不调用
* 好处:1.每次尺寸发生改变是Path就会被重置,重新绘制
* 2.不会过度的绘制
* 3.
* Path.Direction.CW: 顺时针
* Path.Direction.CCW:逆时针
* @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);
// mPaint.reset();
// mPath.addRect(getWidth() / 2 - 150,getHeight() / 2 - 300 ,getWidth() / 2 + 150,getHeight() / 2 , Path.Direction.CCW);
// mPath.addCircle(getWidth() / 2,getHeight() / 2 ,150, Path.Direction.CW);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// mPath.setFillType(Path.FillType.EVEN_ODD);
// canvas.drawLine(100,100,300,300,mPaint);
// canvas.drawPath(mPath,mPaint);
//画线
canvas.drawArc(getWidth() / 2 - radius,getHeight() / 2 - radius,getWidth() / 2 + radius,getHeight() / 2 + radius,90 + angle / 2,360 - angle,false,mPaint);
/**
* advance:每一个刻度之间的距离
* phase:起始的刻度需要空出的距离
*/
//画刻度
mPaint.setPathEffect(effect);
//画线
canvas.drawArc(getWidth() / 2 - radius,getHeight() / 2 - radius,getWidth() / 2 + radius,getHeight() / 2 + radius,90 + angle / 2,360 - angle,false,mPaint);
mPaint.setPathEffect(null);
//画指针
canvas.drawLine(getWidth() / 2 ,getHeight() / 2,
(float) Math.cos(Math.toRadians(getAngleFromeMark(5))) * UIUtils.dp2px(120) + getWidth() / 2,
(float) Math.sin(Math.toRadians(getAngleFromeMark(5))) * UIUtils.dp2px(120) + getHeight() / 2,
mPaint);
}
public int getAngleFromeMark(int mark){
return (int) (90 + angle / 2 + (360 - angle) / 20 * mark);
}
}
4.2.饼图
/**
* 饼图
* 实现思路:
* 1.循环绘制相应的圆弧
* 2.每次修改画笔的颜色,修改圆弧的起始和扫描过的角度。
* 3.当绘制凸起的圆弧时平移画布,进行绘制
* 4.绘制完成后恢复画布
*/
public class PieChart extends View {
private Paint mPaint;
private static final float radius = UIUtils.dp2px(150);
private static final float TYPE_TWO = 2;
private int[] angle = {60,100,120,80}; //角度
private int[] colors = {Color.parseColor("#817936"),Color.parseColor("#444693"),Color.parseColor("#f391a9"),Color.parseColor("#826858")}; //颜色
public PieChart(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
// mPaint.setStyle(Paint.Style.STROKE);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int currentAngle = 0; //当前角度
for (int i = 0; i < angle.length; i++) {
mPaint.setColor(colors[i]);
canvas.save();
if (i == TYPE_TWO){
canvas.translate(-30,-30); //将画布平移 此处简单处理,需要根据角度计算。
}
canvas.drawArc(getWidth() / 2 -radius,getHeight() / 2 - radius ,getWidth() / 2 + radius,getHeight() / 2 + radius,currentAngle,angle[i],true,mPaint);
canvas.restore();
currentAngle+=angle[i]; //每次绘制玩,当前角度递增
}
}
}
网友评论