自定义汽车仪表盘

自定义汽车仪表盘

效果图:

这里写图片描述

获取控件的宽高
 @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        mWidth = w;
        mHeight = h;
        mCenterX = mWidth / 2f;
        mCenterY = mHeight / 2f;
        mRadius = (mHeight - offset * 2) / 2;
    }
初始化画笔:
//最外层大圆弧的画笔
        outerArcPaint = new Paint();
        outerArcPaint.setStyle(Paint.Style.STROKE);
        outerArcPaint.setStrokeWidth(mStrokeWidth);
        outerArcPaint.setColor(Color.parseColor("#5555aa"));
        outerArcPaint.setAntiAlias(true);//防止边缘锯齿

        //最外层小圆弧的画笔
        outerSmallArcPaint = new Paint();
        outerSmallArcPaint.setAntiAlias(true);//防止边缘锯齿
        outerSmallArcPaint.setStyle(Paint.Style.STROKE);
        outerSmallArcPaint.setStrokeCap(Paint.Cap.ROUND);//设置线冒样式,取值有Cap.ROUND(圆形线冒)、Cap.SQUARE(方形线冒)、Paint.Cap.BUTT(无线冒)
        outerSmallArcPaint.setStrokeWidth(dp2px(3));
        SweepGradient sweepGradient = new SweepGradient(mCenterX, mCenterY, mColors, null);
        outerSmallArcPaint.setShader(sweepGradient);//填充颜色


        //内部圆的画笔
        insideCirclePaint = new Paint();
        insideCirclePaint.setColor(Color.parseColor("#27408B"));
        insideCirclePaint.setStyle(Paint.Style.FILL);
        insideCirclePaint.setAntiAlias(true);//防止边缘锯齿

        //绘制速度值的画笔
        speedPaint = new Paint();
        speedPaint.setColor(Color.parseColor("#ff0000"));
        speedPaint.setAntiAlias(true);//防止边缘锯齿
        speedPaint.setStrokeWidth(4);

        //刻度线的画笔
        scaleLinePaint = new Paint();
        scaleLinePaint.setStrokeWidth(4);
        scaleLinePaint.setAntiAlias(true);//防止边缘锯齿
        scaleLinePaint.setColor(Color.parseColor("#ECEFF1"));

        //刻度数字的画笔
        scaleTextPaint = new Paint();
        scaleTextPaint.setTextSize(sp2px(16));
        scaleTextPaint.setTypeface(Typeface.DEFAULT);
        scaleTextPaint.setColor(Color.parseColor("#ECEFF1"));
        scaleTextPaint.setAntiAlias(true);//防止边缘锯齿
        mRectText = new Rect();

        //绘制单位km/h的画笔
        unitTextPaint = new Paint();
        unitTextPaint.setColor(Color.parseColor("#ECEFF1"));
        unitTextPaint.setAntiAlias(true);//防止边缘锯齿
        unitTextPaint.setTypeface(Typeface.DEFAULT);
        unitTextPaint.setTextSize(sp2px(16));
        unitTextPaint.setTextAlign(Paint.Align.CENTER);

        //指针的画笔
        pointerPaint = new Paint();
        pointerPaint.setStrokeCap(Paint.Cap.ROUND);//设置线的两端为圆弧
        pointerPaint.setColor(Color.parseColor("#55aaaa"));
        pointerPaint.setStrokeWidth(dp2px(3));
画圆弧
private void drawArc(Canvas canvas) {

        //画外部大圆弧
        RectF mRectFArc = new RectF((mWidth - mHeight) / 2 + offset, offset, mWidth - (mWidth - mHeight) / 2 - offset, mHeight - offset);
        canvas.drawArc(mRectFArc, mStartAngle - 15, mSweepAngle + 30, false, outerArcPaint);

        //画外部小圆弧
        RectF mSmallRectFArc = new RectF((mWidth - mHeight) / 2 + offset + mLength1, offset + mLength1, mWidth - (mWidth - mHeight) / 2 - offset - mLength1, mHeight - offset - mLength1);
        canvas.drawArc(mSmallRectFArc, mStartAngle - 15 + mSweepAngle + 30 - 360, 360 - (mSweepAngle + 30), false, outerSmallArcPaint);

        //画内部中心圆
        canvas.drawCircle(mCenterX, mCenterY, mRadius / 2, insideCirclePaint);

    }
绘制文本
private void drawText(Canvas canvas) {

        //绘制速度值
        int xOffset = dp2px(22);
        if (mVelocity >= 100) {
            drawDigitalTube(canvas, mVelocity / 100, -xOffset);
            drawDigitalTube(canvas, (mVelocity - 100) / 10, 0);
            drawDigitalTube(canvas, mVelocity % 100 % 10, xOffset);
        } else if (mVelocity >= 10) {
            drawDigitalTube(canvas, -1, -xOffset);
            drawDigitalTube(canvas, mVelocity / 10, 0);
            drawDigitalTube(canvas, mVelocity % 10, xOffset);
        } else {
            drawDigitalTube(canvas, -1, -xOffset);
            drawDigitalTube(canvas, -1, 0);
            drawDigitalTube(canvas, mVelocity, xOffset);
        }

        //绘制单位km/h
        canvas.drawText(mHeaderText, mWidth / 2, mHeight / 2 + unitTextPaint.getTextSize() + offset, unitTextPaint);

    }
画刻度
private void drawScale(Canvas canvas) {

        /**
         * 画长刻度
         * 画好起始角度的一条刻度后通过canvas绕着原点旋转来画剩下的长刻度
         */
        double cos = Math.cos(Math.toRadians(mStartAngle - 180));
        double sin = Math.sin(Math.toRadians(mStartAngle - 180));
        int xOff = (mWidth - mHeight) / 2 + offset + mStrokeWidth / 2;
        int yOff = offset - mStrokeWidth / 2;

        float x0 = (float) (xOff + mRadius * (1 - cos));
        float y0 = (float) (yOff + mRadius * (1 - sin));
        float x1 = (float) (xOff + mRadius - (mRadius - mLength1) * cos);
        float y1 = (float) (yOff + mRadius - (mRadius - mLength1) * sin);

        canvas.save();
        canvas.drawLine(x0, y0, x1, y1, scaleLinePaint);
        float angle = mSweepAngle * 1f / mSection;
        for (int i = 0; i < mSection; i++) {
            canvas.rotate(angle, mCenterX, mCenterY);
            canvas.drawLine(x0, y0, x1, y1, scaleLinePaint);
        }
        canvas.restore();


        //画刻度读数
        float α;
        float[] p;
        angle = mSweepAngle * 1f / mSection;
        for (int i = 0; i <= mSection; i++) {
            α = mStartAngle + angle * i;
            p = getCoordinatePoint(mRadius - mLength2, α);
            if (α % 360 > 135 && α % 360 < 225) {
                scaleTextPaint.setTextAlign(Paint.Align.LEFT);
            } else if ((α % 360 >= 0 && α % 360 < 45) || (α % 360 > 315 && α % 360 <= 360)) {
                scaleTextPaint.setTextAlign(Paint.Align.RIGHT);
            } else {
                scaleTextPaint.setTextAlign(Paint.Align.CENTER);
            }
            scaleTextPaint.getTextBounds(mHeaderText, 0, mTexts[i].length(), mRectText);
            int txtH = mRectText.height();
            if (i <= 1 || i >= mSection - 1) {
                canvas.drawText(mTexts[i], p[0], p[1] + txtH / 2, scaleTextPaint);
            } else if (i == 3) {
                canvas.drawText(mTexts[i], p[0] + txtH / 2, p[1] + txtH, scaleTextPaint);
            } else if (i == mSection - 3) {
                canvas.drawText(mTexts[i], p[0] - txtH / 2, p[1] + txtH, scaleTextPaint);
            } else {
                canvas.drawText(mTexts[i], p[0], p[1] + txtH, scaleTextPaint);
            }
        }
    }
画指针
private void drawPointer(Canvas canvas) {
        float θ = mStartAngle + mSweepAngle * (mVelocity - mMin) / (mMax - mMin); // 指针与水平线夹角
        float[] p1 = getCoordinatePoint(mRadius - mStrokeWidth, θ);
        float[] p2 = getCoordinatePoint(mRadius / 10 * 6, θ);
        canvas.drawLine(p1[0], p1[1], p2[0], p2[1], pointerPaint);
    }
下载地址:

源码下载

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值