刻度表盘源码分析



public class DashBoardView extends View {

    private Context context;
    //     private Paint mPaint;
    //     private Paint mPaintArc;
    // 弧的外接矩形
    private RectF rectFArc, rectFArc2;
    // text
    private Paint mPaintText;
    // line
    private Paint mPaintLine;
    // 指针路径
    private Path path;
    // 宽、高
    private float width, height;
    private float radius, arcWidth, arcWidth2, arcStrokeWidth, pointerLength, lineLength;
    // 设置旋转角度
    public float degrees = 0;
    private float paddingLeft, paddingTop, paddingRight, paddingBottom;

    // 底部描述文字
    private String desc;

    public DashBoardView(Context context) {
        this(context, null);
    }

    public DashBoardView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DashBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(context.getResources().getColor(R.color.zs));
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);

        mPaintArc = new Paint();
        // 空心
        mPaintArc.setStyle(Paint.Style.STROKE);
        mPaintArc.setAntiAlias(true);

        mPaintLine = new Paint();
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        mPaintLine.setStyle(Paint.Style.FILL);
        mPaintLine.setAntiAlias(true);

        path = new Path();

        mPaintText = new Paint();
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        mPaintText.setAntiAlias(true);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int wMode = MeasureSpec.getMode(widthMeasureSpec);
        int wSize = MeasureSpec.getSize(widthMeasureSpec);
        int hMode = MeasureSpec.getMode(heightMeasureSpec);
        int hSize = MeasureSpec.getSize(heightMeasureSpec);

        // 处理宽高为 wrap_content的情况
        if (wMode == MeasureSpec.AT_MOST && hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, 200);
        } else if (wMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(200, hSize);
        } else if (hMode == MeasureSpec.AT_MOST) {
            setMeasuredDimension(wSize, 200);
        }

        // 获取padding
        paddingLeft = getPaddingLeft();
        paddingTop = getPaddingTop();
        paddingRight = getPaddingRight();
        paddingBottom = getPaddingBottom();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        this.width = w - paddingLeft - paddingRight;
        this.height = h - paddingTop - paddingBottom;// 640 850 360-360
        // 外圆弧的半径
        if (width <= height) {
            arcWidth = width / 2;
        } else {
            arcWidth = height / 2;
        }
        // 弧的描边宽度
        arcStrokeWidth = (10 / 180f) * arcWidth;
        // 位于圆心处的圆的半径
        radius = 15 / 180f * arcWidth;
        // 指针的长度
        pointerLength = 110 / 180f * arcWidth;
        // 刻度线的长度
        lineLength = 15 / 180f * arcWidth;
        // 绘制内外弧的画笔
        mPaintArc.setStrokeWidth(arcStrokeWidth);
        // 内圆弧的半径
        arcWidth2 = arcWidth - mPaintArc.getStrokeWidth();
        // 刻度线描边宽度
        mPaintLine.setStrokeWidth(2 / 180f * arcWidth);
        mPaintText.setTextSize(20 / 180f * arcWidth);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        // 注释以下语句会让中心小圆的圆心位于左上角处
        canvas.translate(width / 2 + paddingLeft, height / 2 + paddingTop);
        canvas.drawCircle(0, 0, radius, mPaint);
        // 将画布平移后,(0,0)点的位置就挪动到中间小圆的位置了
        rectFArc = new RectF(-arcWidth, -arcWidth, arcWidth, arcWidth);
        rectFArc2 = new RectF(-arcWidth2, -arcWidth2, arcWidth2, arcWidth2);

        // 绘制外围弧形
        mPaintArc.setColor(context.getResources().getColor(R.color.mainTextBlack));
        /**
         * 矩形范围  开始角度  扫过的角度  是否将弧两端和圆心连接  画笔
         */
        canvas.drawArc(rectFArc, 165, 210, false, mPaintArc);
        // 绘制内围弧形
        mPaintArc.setColor(context.getResources().getColor(R.color.hs));
        canvas.drawArc(rectFArc2, 165, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawArc(rectFArc2, 235, 70, false, mPaintArc);
        mPaintArc.setColor(context.getResources().getColor(R.color.ls));
        canvas.drawArc(rectFArc2, 305, 70, false, mPaintArc);
        // 刻度线的起始位置 (理解-的含义)  从内弧边界一定距离开始
        float startXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth);
        // 刻度线的终止位置
        float stopXLine = -(arcWidth2 - (1 / 2) * arcStrokeWidth - lineLength);
        // 文本的起始位置 (理解-的含义)  从内弧边界一定距离开始
        float startXText = -mPaintText.measureText("") / 2; // 文本的宽度
        float stopXText = -(arcWidth2 - (1 / 2) * mPaintArc.getStrokeWidth() - (2.5f) * lineLength);

        // 绘制""的刻度线
        canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        mPaintText.setColor(context.getResources().getColor(R.color.zs));
        canvas.drawText("", startXText, stopXText, mPaintText);

        mPaintLine.setColor(context.getResources().getColor(R.color.hs));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(-35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.hs));
                canvas.drawText("", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }

        canvas.rotate(105);
        mPaintLine.setColor(context.getResources().getColor(R.color.ls));
        for (int i = 0; i <= 2; i++) {
            canvas.rotate(35);
            if (i == 1) {
                mPaintText.setColor(context.getResources().getColor(R.color.ls));
                canvas.drawText("", startXText, stopXText, mPaintText);
            }
            canvas.drawLine(0, startXLine, 0, stopXLine, mPaintLine);
        }
        // 纠正画布,刚好在""的位置
        canvas.rotate(-105);

        mPaintText.setColor(context.getResources().getColor(R.color.mainTextBlack));
        canvas.drawText(desc, -mPaintText.measureText(desc) / 2, pointerLength, mPaintText);
        // 画笔坐标系旋转
        canvas.rotate(-105 + degrees);
        // 绘制指针
        mPaintLine.setColor(context.getResources().getColor(R.color.zs));
        path.moveTo(radius / 2, 0);
        path.lineTo(0, -pointerLength);
        path.lineTo(-radius / 2, 0);
        canvas.drawPath(path, mPaintLine);
    }

    /**
     * 设置旋转角度
     */
    public void setDegrees(float degrees) {
        this.degrees = degrees;
        invalidate();
    }

    /**
     * 获取旋转角度
     */
    public float getDegrees() {
        return this.degrees;
    }

    /**
     * 设置底部描述
     */
    public void setTextDesc(String desc) {
        this.desc = desc;
        invalidate();
    }


}
private void initView() {
    dashBoardView = (DashBoardView) findViewById(R.id.dashBoardView);

    // 账户安全 仪表盘
    ObjectAnimator animator = ObjectAnimator.ofFloat(dashBoardView,"degrees", 175);
    animator.setDuration(3000);
    // 设置插值器
    animator.setInterpolator(new DecelerateInterpolator());
    animator.start();

    dashBoardView.setTextDesc("你的账户等级  高");

}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="zxxk.ext.dashboardview.MainActivity">

    <zxxk.ext.dashboardview.DashBoardView
        android:id="@+id/dashBoardView"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:padding="50dp" />
</RelativeLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值