腾讯管家测网速控件仿写

先看一下腾讯管家的测速控件
这里写图片描述

其中可以看出来测速控件分为两个作用一个是测量延时,一个是测网速
所以可以将控件分为两部分,然后用一个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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值