自定义view之刻度盘

效果

自己动手写了一个自定义圆盘,效果如下:
这里写图片描述

思路

一些颜色,字体细节没有调,自定义属性也没有加上去,这些都比较简单!说下思路吧:
这个控件看起来比较复杂,其实经过分解也很简单,这些东西都是通过canvas,paint画出来的,麻烦一点的是计算坐标.下面是几个注意点:

1.使用getWidth()时需要测量onMeasure.
2.Paint创建的事件不要在onDraw.
3.画刻度的时候,可以通过正余玄来计算,但是比较麻烦,我通过旋转坐标系来实现的,坐标系旋转之后要记得旋转回来.

代码

下面是所有代码


public class PanView extends View {
    private int mWidth;
    private int mHeight;
    private int innerCircleWidth1 = 10;
    private int innerCircleWidth2 = 4;
    private int innerLineWidth = 8;
    private int outerCircleWidth1 = 2;
    private int outerCircleWidth2 = 80;
    private int mFirstColor = Color.BLUE;
    private int mSecondColor = Color.WHITE;
    private Paint mPaint;
    private Paint mTextPaint;
    private int mPercent = 0;

    // 里面圆的半径
    private int innerReduis1 = 15;
    private int innerReduis2 = 35;
    private String mText = "";

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

    public PanView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setColor(mFirstColor);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);

        mTextPaint = new Paint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        if (widthMode == MeasureSpec.EXACTLY) {

            mWidth = width;
        } else {
            mWidth = 400;
        }
        if (heightMode == MeasureSpec.EXACTLY) {
            mHeight = height;
        } else {
            mHeight = 400;
        }

        setMeasuredDimension(mWidth, mHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        // 确定圆心
        int circleX = mWidth / 2;
        int circleY = mHeight / 2;

        Log.d("ch", circleX + "");
        Log.d("ch", circleY + "");

        // 画里面的园
        drawInnerCircle(canvas, circleX, circleY);
        // 画线
        drawIndicator(canvas, circleX, circleY, innerReduis1);
        // 画最外面的圆弧
        drawouterArc1(canvas, circleX, circleY);
        // 画内侧的圆弧
        drawOuterArc2(canvas, circleX, circleY);
        //画正方形
        drawRect(canvas, circleX, circleY);
        // 画文字
        drawText(canvas, circleX, circleY);
    }

    private void drawText(Canvas canvas, int circleX, int circleY) {
        mTextPaint.setTextSize(30);
        mTextPaint.setColor(Color.RED);
        mText = "已完成";
        float textLength = mTextPaint.measureText(mText);
        canvas.drawText(mText, (circleX - textLength / 2), circleY + 250, mTextPaint);
    }

    private void drawRect(Canvas canvas, int circleX, int circleY) {
        mPaint.setStrokeWidth(20);
        mPaint.setColor(Color.BLUE);
        float left = circleX - 20;
        float top = circleY + 170;
        float right = circleX + 20;
        float bottom = top + 20;
        canvas.drawRect(left, top, right, bottom, mPaint);
    }

    private void drawOuterArc2(Canvas canvas, int circleX, int circleY) {
        int outerReduis2 = 200;
        int left = circleX - outerReduis2;
        int top = circleY - outerReduis2;
        int right = circleX + outerReduis2;
        int bottom = circleY + outerReduis2;
        RectF oval = new RectF(left, top, right, bottom);
        float startAngle = 45;
        float sweepAngle = -270;
        mPaint.setColor(Color.GRAY);
        mPaint.setStrokeWidth(outerCircleWidth2);
        canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);
        float degree = (sweepAngle / 100f) * mPercent;

        mPaint.setColor(Color.GREEN);
        canvas.drawArc(oval, startAngle + 90, -degree, false, mPaint);
    }

    private void drawouterArc1(Canvas canvas, int circleX, int circleY) {

        int outerReduis1 = 300;
        int left = circleX - outerReduis1;
        int top = circleY - outerReduis1;
        int right = circleX + outerReduis1;
        int bottom = circleY + outerReduis1;
        RectF oval = new RectF(left, top, right, bottom);
        float startAngle = 31;
        float sweepAngle = -242;
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(outerCircleWidth1);
        canvas.drawArc(oval, startAngle, sweepAngle, false, mPaint);

        //画外侧的间隔线
        int lineLength = 25;
        int count = 9;
        float degree = 24.2f;
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(outerCircleWidth1);
        canvas.drawLine(circleX, top, circleX, top + lineLength, mPaint);
        for (int i = 0; i < 5; i++) {

            canvas.rotate(degree, circleX, circleY);
            canvas.drawLine(circleX, top, circleX, top + lineLength, mPaint);
        }
        canvas.rotate(-121, circleX, circleY);

        for (int i = 0; i < 5; i++) {

            canvas.rotate(-degree, circleX, circleY);
            canvas.drawLine(circleX, top, circleX, top + lineLength, mPaint);
        }
        canvas.rotate(121, circleX, circleY);
    }

    private void drawInnerCircle(Canvas canvas, int circleX, int circleY) {

        int left = circleX - innerReduis2;
        int top = circleX - innerReduis2;
        int right = circleX + innerReduis2;
        int bottom = circleX + innerReduis2;
        Rect rect = new Rect(left, top, right, bottom);

        mPaint.setStrokeWidth(innerCircleWidth2);
        canvas.drawCircle(circleX, circleY, innerReduis2, mPaint);
        mPaint.setStrokeWidth(innerCircleWidth1);
        canvas.drawCircle(circleX, circleY, innerReduis1, mPaint);

    }

    private void drawIndicator(Canvas canvas, int circleX, int circleY, int innerReduis1) {
        float startX = circleX;
        float startY = circleY - innerCircleWidth1 / 2;
        float stopX = circleX;
        float stopY = circleY - 200;
        mPaint.setStrokeWidth(innerLineWidth);
        mPaint.setColor(Color.YELLOW);
        float degree = (float) (1.21 * mPercent) * 2 - 121;
        canvas.rotate(degree, circleX, circleX);
        canvas.drawLine(startX, startY, stopX, stopY, mPaint);
        canvas.rotate(-degree, circleX, circleX);
    }

    public void setPersent(int persent) {

        mPercent = persent;
        invalidate();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值