自定义View - 9.圆形进度条

oyijc-44uv6.gif

1.自定义属性

首先有没有自定义属性,比如这里的圆环的宽度,外圆的颜色,中间文字的大小和颜色都不是写死的,所以需要自定义属性

<resources>
    <declare-styleable name="ProgressBar">
        <!--圆环宽度-->
        <attr name="ringWidth" format="dimension" />
        <!--外圆颜色-->
        <attr name="outCircleColor" format="color" />
        <!--进度圆颜色-->
        <attr name="innerCircleColor" format="color" />
        <!--中间文字的大小-->
        <attr name="centerTextSize" format="dimension" />
        <!--中间文字的颜色-->
        <attr name="centerTextColor" format="color" />
    </declare-styleable>
</resources>
       public ProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        //获取自定义属性
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ProgressBar);
        mRingWidth = typedArray.getDimensionPixelOffset(R.styleable.ProgressBar_ringWidth,
                DimenUtils.dip2px(context, mRingWidth));
        mOutCircleColor = typedArray.getColor(R.styleable.ProgressBar_outCircleColor, mOutCircleColor);
        mInnerCircleColor = typedArray.getColor(R.styleable.ProgressBar_innerCircleColor, mInnerCircleColor);
        mCenterTextSize = typedArray.getDimensionPixelOffset(R.styleable.ProgressBar_centerTextSize,
                DimenUtils.dip2px(context, mCenterTextSize));
        mCenterTextColor = typedArray.getColor(R.styleable.ProgressBar_centerTextColor, mCenterTextColor);
        typedArray.recycle();
    }

2. 测量

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //默认大小
        int defaultSize = DimenUtils.dip2px(getContext(), 100);
        //宽度
        //获取模式
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        //获取大小
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        //包裹内容
        if (widthMode == MeasureSpec.AT_MOST) {
            widthSize = defaultSize;
        }
        //高度
        //获取模式
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        //获取大小
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //包裹内容
        if (heightMode == MeasureSpec.AT_MOST) {
            heightSize = defaultSize;
        }
        //宽高要一致
        int progressSize = Math.min(widthSize, heightSize);

        //设置宽高
        setMeasuredDimension(progressSize, progressSize);
    }

3.绘制

3.1 绘制外圆

    @Override
    protected void onDraw(Canvas canvas) {
        // 1.绘制外圆
        int cx = getWidth() / 2;
        int cy = getHeight() / 2;
        float radius = getWidth() / 2 - mRingWidth / 2;
        canvas.drawCircle(cx, cy, radius, mOutCirclePaint);
     }

3.2 绘制进度圆

  @Override
    protected void onDraw(Canvas canvas) {

        //2.绘制进度圆
        float currentProgress = (float) (mCurrentPercentage * 360);
        if (mOval == null) {
            mOval = new RectF(mRingWidth / 2, mRingWidth / 2,
                    getWidth() - mRingWidth / 2, getHeight() - mRingWidth / 2);
        }
        canvas.drawArc(mOval, 0, currentProgress, false, mInnerCirclePaint);
    }

3.3 绘制中间文本

    protected void onDraw(Canvas canvas) {
        //3.绘制中间文本
        String text = (int) (mCurrentPercentage * 100) + "%";
        //字体的宽度高度
        if (mBounds == null) {
            mBounds = new Rect();
        }
        mCenterTextPaint.getTextBounds(text, 0, text.length(), mBounds);
        float x = getWidth() / 2 - mBounds.width() / 2;
        //知道中间位置求基线位置
        Paint.FontMetricsInt fontMetricsInt = mCenterTextPaint.getFontMetricsInt();
        //指定中间位置,绘制文本
        int baseLine = getHeight() / 2 + (fontMetricsInt.bottom - fontMetricsInt.top) / 2 - fontMetricsInt.bottom;
        canvas.drawText(text, x, baseLine, mCenterTextPaint);
    }

完整代码:progressbar

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容