超简单仿QQ步数显示控件

本着写文即学习的态度,记录下自定义一款超简单仿QQ步数加载控件,话不多数先看图。

这里写图片描述

一,特性:

1,外圈大圆、进度圆和数字显示的颜色均可以自定义
2,设置最大值和当前值
3,设置加载持续时间

二,实现:

1,画外圈大圆
2,画内圈进度圆
3,画文字

在第二步与第三步要根据设置的最大值和当前值动态持续更新进行绘画,这里我使用valueAnimation获取中间值。

  • 自定义属性
    <declare-styleable name="CircleProgressView">
        <attr name="circle_process_stroke_width" format="dimension" />
        <attr name="circle_process_stroke_color" format="color" />
        <attr name="circle_process_progress_color" format="color" />
        <attr name="circle_process_text_color" format="color" />
        <attr name="circle_process_text_size" format="dimension" />
        <attr name="circle_process_duration" format="dimension"/>
    </declare-styleable>
  • 自定义CircleProgressView继承自view,获取属性值
    private void initAttrs(AttributeSet attrs) {
        TypedArray attribute = getContext().obtainStyledAttributes(attrs, R.styleable.CircleProgressView);
        mCircleColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_stroke_color, Color.BLUE);
        mProgressColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_progress_color, Color.RED);
        mRoundWidth = (int) attribute.getDimension(R.styleable.CircleProgressView_circle_process_stroke_width, 1f);
        mTextColor = attribute.getColor(R.styleable.CircleProgressView_circle_process_text_color, 0XFFFC00D1);
        mTextSize = (int) attribute.getDimension(R.styleable.CircleProgressView_circle_process_text_size, 20f);
        mDuration = (long) attribute.getDimension(R.styleable.CircleProgressView_circle_process_duration,2000f);
        attribute.recycle();
    }
  • 测量
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mViewWidth = MeasureSpec.getSize(widthMeasureSpec);
        mViewHeight = MeasureSpec.getSize(heightMeasureSpec);
        centerX = mViewWidth / 2;
        centerY = mViewHeight / 2;
        radius = Math.min(centerX, centerY) - mRoundWidth;//半径
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
  • 画外圈大圆
        //画外圈大圆
        mPaint.setColor(mCircleColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mRoundWidth);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        canvas.drawCircle(centerX, centerY, radius, mPaint);
  • 画进度圆
        //根据比值画进度圆
        mPaint.setColor(mProgressColor);
        RectF rectF = new RectF(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
        float curRadius = process * 360;
        canvas.drawArc(rectF, 90f, curRadius, false, mPaint);
  • 画数字
        //根据比值画文字
        mPaint.reset();
        mPaint.setAntiAlias(true);
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        String text = (int) (process * mMaxNum) + "/" + (int) mMaxNum;
        Rect textBound = new Rect();
        mPaint.getTextBounds(text, 0, text.length(), textBound);
        int textStart = (mViewWidth - textBound.width()) / 2;
        Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
        int baseLine = (int) (mViewHeight / 2 + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom);
        canvas.drawText(text, textStart, baseLine, mPaint);
  • 还有一个最重要的方法,开始动画,产生中间值,计算比值
/**
     * 开始动画
     *
     * @param maxNum 最大值
     * @param curNum 当前值
     */
    public synchronized void start(final float maxNum, float curNum) {
        if (maxNum <= 0)
            throw new IllegalArgumentException("maxNum 必须大于0");
        if (curNum < 0)
            throw new IllegalArgumentException("curNum 不能小于0");
        if (curNum > maxNum)
            throw new IllegalArgumentException("curNum 不能大于maxNum");
        mMaxNum = maxNum;
        ValueAnimator animator = ValueAnimator.ofFloat(0, curNum);
        animator.setDuration(mDuration);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                //计算得到比值
                process = value / maxNum;
                invalidate();
            }
        });
        animator.start();
    }

至此功能已经初步完成了,可以另外提供一些方法方便使用

/**
     * 设置描边宽度
     *
     * @param width
     */
    public synchronized void setRoundWidth(int width) {
        if (width > 0) {
            mRoundWidth = width;
        }
    }

    /**
     * 设置动画执行时间,单位ms
     * @param duration
     */
    public synchronized void setDuration(long duration) {
        if (duration > 0) {
            mDuration = duration;
        }
    }

    /**
     * 设置外圈大圆颜色
     *
     * @param color
     */
    public synchronized void setCircleColor(int color) {
        mCircleColor = color;
    }

    /**
     * 设置进度圆颜色
     *
     * @param color
     */
    public synchronized void setProgressColor(int color) {
        mProgressColor = color;
    }

    /**
     * 设置文字颜色
     *
     * @param color
     */
    public synchronized void setTextColor(int color) {
        mTextColor = color;
    }

大功告成,简单的功能实现,希望能抛砖引玉啦!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值