标签:绘制 地址 区间 hsi 最大 文字 hardware 支付 高度
首先是自定义一些属性,可自己再添加,挺基础的,上代码
<?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