如何绘制一个仪表盘
发布于: 刚刚
学习使用 Paint/Path/PathMeasure/PathDashPathEffect 来绘制一个仪表盘
PathMeasure:支持 Path 路径的测量,还有路径上任意距离的点的位置和角度
PathDashPathEffect:用指定的形状标记绘制的路径,可以通过 Paint.setPathEffect 设置给画笔,用于绘制表盘
public class Dashboard extends View {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private static final int ANGLE = 120;
private static final float RADIUS = Util.dp2px(150);
private static final float LENGTH = Util.dp2px(120);
private static final int count = 20;
private PathMeasure pathMeasure;
Path dash = new Path();
PathDashPathEffect effect;
Path arc = new Path();
public Dashboard(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
{
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(Util.dp2px(2));
dash.addRect(0, 0, Util.dp2px(2), Util.dp2px(10), Path.Direction.CW);
}
float pos[] = new float[2];
float tan[] = new float[2];
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
arc = new Path();
arc.addArc(getWidth()/2-RADIUS, getHeight()/2-RADIUS, getWidth()/2+RADIUS, getHeight()/2+RADIUS, 90+ANGLE/2, 360-ANGLE);
pathMeasure = new PathMeasure(arc, false);
float length = pathMeasure.getLength();
float advance = length/(count);//-Util.dp2px(0);
effect = new PathDashPathEffect(dash, advance, 0, PathDashPathEffect.Style.ROTATE);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 画刻度
canvas.drawPath(arc, paint);
// canvas.drawArc(getWidth()/2-RADIUS, getHeight()/2-RADIUS, getWidth()/2+RADIUS, getHeight()/2+RADIUS, 90+ANGLE/2, 360-ANGLE, false, paint);
paint.setPathEffect(effect);
canvas.drawPath(arc, paint);
// canvas.drawArc(getWidth()/2-RADIUS, getHeight()/2-RADIUS, getWidth()/2+RADIUS, getHeight()/2+RADIUS, 90+ANGLE/2, 360-ANGLE, false, paint);
paint.setPathEffect(null);
// 画指针
// boolean success = pathMeasure.getPosTan(2900, pos, tan);
// if (success)
// canvas.drawLine(getWidth()/2, getHeight()/2, pos[0], pos[1], paint);
int markValue = getMark();
canvas.drawLine(getWidth()/2, getHeight()/2,
(float) Math.cos(Math.toRadians(getAngleFromMark(markValue)))*LENGTH + getWidth()/2,
(float) Math.sin(Math.toRadians(getAngleFromMark(markValue)))*LENGTH + getHeight()/2,
paint);
postDelayed(this::invalidate, 1000);
}
int mark = 0;
int getMark(){
mark++;
if (mark > 20) mark = 0;
return mark;
}
int getAngleFromMark(int mark){
return (int) (90 + (float) ANGLE / 2 + (float)(360-ANGLE)/count*mark);
}
}
复制代码
划线
评论
复制
发布于: 刚刚阅读数: 2
版权声明: 本文为 InfoQ 作者【Changing Lin】的原创文章。
原文链接:【http://xie.infoq.cn/article/1b0dba711d817ec33dee62442】。文章转载请联系作者。
Changing Lin
关注
获得机遇的手段远超于固有常规之上~ 2020.04.29 加入
我能做的,就是调整好自己的精神状态,以最佳的面貌去面对那些未曾经历过得事情,对生活充满热情和希望。
评论