先看一下騰訊管家的測速控件

其中可以看出來測速控件分為兩個作用一個是測量延時,一個是測網速
是以可以将控件分為兩部分,然後用一個ViewGroup将兩個View裝載在一起。
好了,分析的話就說這麼多,下面開始看第一部分測量網絡延時的源碼
`
public class DelayMeterView extends View {
Paint dottedPoint;//最外層畫筆
float time;//動畫時間
float dottedRadius;//外圍圓的半徑
public float getTime() {
return time;
}
public void setDottedRadius(float dottedRadius) {
this.dottedRadius = dottedRadius;
}
public void setTime(float time) {
this.time = time;
invalidate();
}
ObjectAnimator objectAnimator;//動畫
public DelayMeterView(Context context) {
this(context, null);
}
public DelayMeterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public DelayMeterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
dottedPoint = new Paint(Paint.ANTI_ALIAS_FLAG);
objectAnimator = ObjectAnimator.ofFloat(this, "time", 0, 60);
objectAnimator.setDuration(1000 * 5);
objectAnimator.setInterpolator(new LinearInterpolator());
objectAnimator.setRepeatCount(ValueAnimator.INFINITE);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e("onDraw", "onDraw333");
canvas.translate(getWidth() / 2, getHeight() / 2);
canvasDotted(canvas);
}
public void canvasDotted(Canvas canvas) {
PathEffect pathEffect = new DashPathEffect(new float[]{10, 5}, 10);//畫虛線
dottedPoint.setPathEffect(pathEffect);
dottedPoint.setColor(Color.parseColor("#C4E7D5"));
dottedPoint.setStyle(Paint.Style.STROKE);
dottedPoint.setStrokeWidth(10);
RectF rectF = new RectF(-dottedRadius, -dottedRadius, dottedRadius, dottedRadius);
canvas.drawArc(rectF, 135, 270 * (time / 60), false, dottedPoint);
}
public void setAnimaStart() {
Log.e("", "");
objectAnimator.start();
}
public void stopAniam() {
objectAnimator.end();
}
}
`
這段代碼就不用解釋了 就是畫一個最外圍的圓環 其中canvasDotted方法需要看一下
下面是第二部分測量網速的view
`
public class SpeedMeterView extends View {
Paint unitPaint;//機關的畫筆
Paint pointerPaint;//指針畫筆
Paint textPaint;//實際網速的畫筆
String textUnit = "KB/s";
int value = 0;//預設網速
Rect textRect = new Rect();
float preAngle = 0;//前一個指針偏轉的角度
float nextAngle = 0;//前一個指針偏轉的角度
float smallRadius = 120; //小圓半徑
ObjectAnimator objectAnimator;
float time;
float angle = 0;//偏轉角度
public float getTime() {
return time;
}
public void setTime(float time) {
this.time = time;
angle = preAngle + (nextAngle - preAngle) * time / 100;
invalidate();
}
public int getValue() {
return value;
}
public void setValue(int value) {
if (!objectAnimator.isRunning()) {
this.value = value;
setAngle();
objectAnimator.start();
}
}
/**
* 計算偏轉角度 角度按照50 45 40 35 30 25 20 配置設定
*/
public void setAngle() {
if (value < 64) {
nextAngle = value * 50 / 64;
} else if (value < 128) {
nextAngle = 50 + (value - 64) * 45 / 64;
} else if (value < 256) {
nextAngle = 50 + 45 + (value - 128) * 40 / 128;
} else if (value < 512) {
nextAngle = 50 + 45 + 40 + (value - 256) * 35 / 256;
} else if (value < 1024) {
nextAngle = 50 + 45 + 40 + 35 + (value - 512) * 30 / 512;
} else if (value < 5120) {
nextAngle = 50 + 45 + 40 + 35 + 30 + value * 25 / 4096;
} else {
nextAngle = 50 + 45 + 40 + 35 + 30 + 25 + value * 20 / 4096;
}
}
public SpeedMeterView(Context context) {
this(context, null);
}
public SpeedMeterView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SpeedMeterView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
pointerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
unitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
pointerPaint.setStrokeWidth(6);
objectAnimator = ObjectAnimator.ofFloat(this, "time", 0, 100);
objectAnimator.setDuration(300);
objectAnimator.setInterpolator(new LinearInterpolator());
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Log.e("onDraw", "onDraw222");
canvas.translate(getWidth() / 2, getHeight() / 2);
canvasNum(canvas);
canvasUnit(canvas);
canvasPointer(canvas);
}
/**
* 繪制網速數字
*
* @param canvas
*/
public void canvasNum(Canvas canvas) {
textPaint.setColor(Color.parseColor("#000000"));
textPaint.setFakeBoldText(true);
String num = value + "";
textPaint.setTextSize(50);
textPaint.getTextBounds(num, 0, num.length(), textRect);
canvas.drawText(num, -textRect.width() / 2, textRect.height() / 2, textPaint);
}
/**
* 繪制機關
*
* @param canvas
*/
public void canvasUnit(Canvas canvas) {
unitPaint.setColor(Color.parseColor("#8f8f8f"));
Rect rect = new Rect();
unitPaint.setTextSize(26);
unitPaint.getTextBounds(textUnit, 0, textUnit.length(), rect);
canvas.drawText(textUnit, -rect.width() / 2, rect.height() / 2 + textRect.height() / 2 + 20, unitPaint);
}
/**
* 繪制指針
*
* @param canvas
*/
public void canvasPointer(Canvas canvas) {
float startX = (float) (smallRadius * Math.cos((135 + angle) * Math.PI / 180));
float startY = (float) (smallRadius * Math.sin((135 + angle) * Math.PI / 180));
float startX1 = (float) (220 * Math.cos((135 + angle) * Math.PI / 180));
float startY1 = (float) (220 * Math.sin((135 + angle) * Math.PI / 180));
Shader shader1 = new LinearGradient(startX, startY, startX1, startY1, Color.parseColor("#eee9eb"),
Color.parseColor("#D69087"), Shader.TileMode.CLAMP);
pointerPaint.setShader(shader1);
pointerPaint.setStrokeCap(Paint.Cap.ROUND);
canvas.drawLine(startX, startY, startX1, startY1, pointerPaint);
}
`
這段代碼畫的東西有很多 不過都有注釋 耐心看一下 應該能看懂
最後就是用ViewGroup組裝兩個view 效果圖
git位址:https://github.com/flyMountain/TianTianQuan