码迷,mamicode.com
首页 > 移动开发 > 详细

Android自定义view之仿支付宝芝麻信用仪表盘

时间:2017-01-11 16:02:01      阅读:324      评论:0      收藏:0      [点我收藏+]

标签:绘制   地址   区间   hsi   最大   文字   hardware   支付   高度   

自定义view练习 仿支付宝芝麻信用的仪表盘

对比图:
技术分享
技术分享
技术分享




首先是自定义一些属性,可自己再添加,挺基础的,上代码

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="RoundIndicatorView">
        <!--最大数值-->
        <attr name="maxNum" format="integer"/>
        <!--圆盘起始角度-->
        <attr name="startAngle" format="integer"/>
        <!--圆盘扫过的角度-->
        <attr name="sweepAngle" format="integer"/>
    </declare-styleable>
</resources>

接着在构造方法里初始化自定义属性和画笔:

private void initAttr(AttributeSet attrs) {
    TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.RoundIndicatorView);
    maxNum = array.getInt(R.styleable.RoundIndicatorView_maxNum,500);
    startAngle = array.getInt(R.styleable.RoundIndicatorView_startAngle,160);
    sweepAngle = array.getInt(R.styleable.RoundIndicatorView_sweepAngle,220);
    //内外圆弧的宽度
    sweepInWidth = dp2px(8); 
    sweepOutWidth = dp2px(3); 
    array.recycle();
}

private void initPaint() {
    paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setDither(true);
    paint.setStyle(Paint.Style.STROKE);
    paint.setColor(0xffffffff);
    paint_2 = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint_3 = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint_4 = new Paint(Paint.ANTI_ALIAS_FLAG);
}

接下来重写onMeasure,也是比较简单,对于不是确定值的直接给定300*400的大小:

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int wSize = MeasureSpec.getSize(widthMeasureSpec);

    int wMode = MeasureSpec.getMode(widthMeasureSpec);

    int hSize = MeasureSpec.getSize(heightMeasureSpec);

    int hMode = MeasureSpec.getMode(heightMeasureSpec);



    if (wMode == MeasureSpec.EXACTLY ){

        mWidth = wSize;

    }else {

        mWidth =dp2px(300);

    }

    if (hMode == MeasureSpec.EXACTLY ){

        mHeight= hSize;

    }else {

        mHeight =dp2px(400);

    }

    setMeasuredDimension(mWidth,mHeight);

}


核心部分onDraw来了,注意圆的半径不要在构造方法里就去设置,那时候是得不到view的宽高值的,所以我在onDraw方法里设置半径,默认就view宽度的1/4吧。把原点移到view的中心去:

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    radius = getMeasuredWidth()/4; //不要在构造方法里初始化,那时还没测量宽高
    canvas.save();
    canvas.translate(mWidth/2,(mWidth)/2);
    drawRound(canvas);  //画内外圆弧
    drawScale(canvas);//画刻度
    drawIndicator(canvas); //画当前进度值
    drawCenterText(canvas);//画中间的文字
    canvas.restore();
}

步骤清晰,按顺序画出仪表盘的四个部分,我们一个一个部分的看

drawRound():这个很简单,内外圆弧所需的属性都已经定义好了,画笔是白色的,我们通过setAlpha()设置一下它的透明度,范围是00~ff。

private void drawRound(Canvas canvas) {
    canvas.save();
    //内圆
    paint.setAlpha(0x40);
    paint.setStrokeWidth(sweepInWidth);
    RectF rectf = new RectF(-radius,-radius,radius,radius);
    canvas.drawArc(rectf,startAngle,sweepAngle,false,paint);
    //外圆
    paint.setStrokeWidth(sweepOutWidth);
    int w = dp2px(10);
    RectF rectf2 = new RectF(-radius-w , -radius-w , radius+w , radius+w);
    canvas.drawArc(rectf