第一次自己动手写东西,觉得写一遍能加深自己的理解,记忆,这个控件是基于别人的基础上改动的
,原文连接 在这里!
第一次弄,不会效果图,大概就是一个刻度盘
先说思路:每一个刻度是一条线条,根据圆心和半径来确定每条线的x,y终点坐标,以及根据圆心和(半径-短线长度)来确定每条线的x,y起点坐标,然后起点到终点画线就可以了。按圆弧的坐标画一百条线条表示刻度盘地盘
再换一个颜色的画笔画上进度,例如90分就画90条
直接上代码;
public class Circle extends View {
private Paint paint;
// 圆半径 线长度
private float r, l;
private float centerX, centerY;
private Shader mShader,mBlurShader;
private float carPoint;
private Canvas canvas;
private static final int TOTAL_PAINT_TIMES = 119; //控制绘制速度,分120次完成绘制
private int mPaintTimes = 0; //当前已经绘制的次数
private double totleAngle = 183.0d;
public Circle(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public Circle(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public Circle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init(){
paint = new Paint();
paint.setStrokeWidth(3);
paint.setAntiAlias(true);
}
@Override
protected void onDraw(final Canvas canvas) {
canvas.save();
for (double angleBack = 180.0d; angleBack <= 540; angleBack += 3.0d) {
float xStartBack = calculateX(r, angleBack);
float xStopBack = calculateX(r - l, angleBack);
float yStartBack = calculateY(r, angleBack);
float yStopBack = calculateY(r - l, angleBack);
paint.setShader(mBlurShader);
//刻度盘分为两种长度的线条
if (angleBack == 510||angleBack == 480||angleBack == 450||angleBack == 420||angleBack == 390||angleBack == 360||angleBack == 210||angleBack == 240||angleBack == 270||angleBack == 300||angleBack == 330){
//长线条位置
paint.setStrokeWidth(4);
float xStartLBack = calculateX(r , angleBack);
float xStopLBack = calculateX((r - l)* 0.95f, angleBack);
float yStartLBack = calculateY(r, angleBack);
float yStopLBack = calculateY((r - l) * 0.95f, angleBack);
canvas.drawLine(xStartLBack, yStartLBack, xStopLBack, yStopLBack, paint); //较长的线
} else if (angleBack>=210&&angleBack<=510) {
//绘制其他位置的线条
paint.setStrokeWidth(3);
canvas.drawLine(xStartBack, yStartBack, xStopBack, yStopBack, paint); // 画短线
}
}
mPaintTimes++;
totleAngle = totleAngle + 3.0d;
for (double angle = 180.0d; angle <= totleAngle; angle += 3.0d) {
float xStart = calculateX(r, angle);
float xStop = calculateX(r - l, angle);
float yStart = calculateY(r, angle);
float yStop = calculateY(r - l, angle);
//绘制进度颜色和底盘颜色
if(angle <= ((float)(carPoint/100)*300+210)&&angle>=210){
paint.setShader(mShader);
}else{
paint.setShader(mBlurShader);}
//刻度盘分为长短两种线条
if (angle == 510||angle == 480||angle == 450||angle == 420||angle == 390||angle == 360||angle == 210||angle == 240||angle == 270||angle == 300||angle == 330){
//长线条
paint.setStrokeWidth(4);
float xStartL = calculateX(r , angle);
float xStopL = calculateX((r - l)* 0.95f, angle);
float yStartL = calculateY(r, angle);
float yStopL = calculateY((r - l) * 0.95f, angle);
canvas.drawLine(xStartL, yStartL, xStopL, yStopL, paint); //较长的线
} else if (angle>=210&&angle<=510) {
//短线条
paint.setStrokeWidth(3);
canvas.drawLine(xStart, yStart, xStop, yStop, paint); // 画短线
}
canvas.restore();
}
//只要没画完就一直刷新onDraw方法重画
if(mPaintTimes <TOTAL_PAINT_TIMES){
invalidate();
}
}
/**
* 根据半径和角度计算x坐标
*/
private float calculateX(float r, double angle) {
angle = angle * ((2 * Math.PI) / 360);
double x = r * Math.sin(angle);
double xFinal = centerX + x;
return (float) xFinal;
}
/**
* 根据半径和角度计算y坐标
*/
private float calculateY(float r, double angle) {
angle = angle * ((2 * Math.PI) / 360);
double y = r * Math.cos(angle);
double yFinal = centerY - y;
return (float) yFinal;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
int viewWidth = getWidth();
int viewHeight = getHeight();
centerX = viewWidth / 2f;
centerY = viewHeight / 2f;
r = viewWidth * 0.4f;
l = viewWidth * 0.03f;
//设置画笔的颜色 可以放入多个颜色变成渐变色 ,因项目需要我用的单色
mBlurShader= new SweepGradient(centerX, centerY, new int[] {
Color.parseColor("#526577"),
Color.parseColor("#526577")
}, null);
mShader = new SweepGradient(centerX, centerY, new int[] {
Color.parseColor("#71D68F"),
Color.parseColor("#71D68F")}, null);
paint.setShader(mShader);
invalidate();
}
public void setPoint(float currentPoint){
carPoint = currentPoint;
invalidate();
}
}
大概讲一下:正上方是0°,所以为了表现从左到右画圆的效果,从180°开始起算,画到540°。