简单实现领取进度圆环

在这里插入图片描述

/**
 *  领取进度
 * @author 
 * @date 2019-3-5
 *
 * 1先初始化 2setNewColor  3setStaticProgressNum/setDynamicProgressNum 设置进度
 */
public class CircleBarView extends View {

    /**
     * 绘制前景圆弧的画笔
     */
    private Paint progressPaint;
    /**
     * 处理动画变化的过程 进度动画
     */
    private CircleBarAnim anim;
    /**
     * 背景圆弧的画笔
     */
    private Paint bgPaint;
    /**
     * 具体的进度条数值
     */
    private float progressNum;
    /**
     * 进度条最大值
     */
    private float maxNum = 100;
    /**
     * 进度条圆弧扫过的角度
     */
    private float progressSweepAngle;
    /**
     * 进度条圆弧颜色
     */
    private int progressColor;
    /**
     * 背景圆弧颜色
     */
    private int bgColor;
    /**
     * 背景圆弧的起始角度
     */
    private float startAngle;
    /**
     * 背景圆弧扫过的角度
     */
    private float sweepAngle;
    /**
     * 圆弧进度条宽度
     */
    private float barWidth;
    /**
     * 绘制圆弧的矩形区域
     */
    private RectF mRectF;
    /**
     * 自定义View默认的宽高
     */
    private int defaultSize;

    public CircleBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {

        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleBarView);
        //默认为绿色
        progressColor = typedArray.getColor(R.styleable.CircleBarView_progress_color, Color.GREEN);
        //默认为灰色
        bgColor = typedArray.getColor(R.styleable.CircleBarView_bg_color, Color.GRAY);

        //默认为0
        startAngle = typedArray.getFloat(R.styleable.CircleBarView_start_angle, 0);
        //默认为360
        sweepAngle = typedArray.getFloat(R.styleable.CircleBarView_sweep_angle, 360);
        //默认为10dp
        barWidth = typedArray.getDimension(R.styleable.CircleBarView_bar_width, SysUtils.dipToPx(context, 10));
        typedArray.recycle();//typedArray用完之后需要回收,防止内存泄漏

        defaultSize = SysUtils.dipToPx(context, 100);

        //进度弧画笔初始化...
        progressPaint = new Paint();
        progressPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
        progressPaint.setAntiAlias(true);//设置抗锯齿
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(barWidth);
        progressPaint.setStrokeCap(Paint.Cap.ROUND);
        //背景弧画笔初始化...
        bgPaint = new Paint();
        bgPaint.setStyle(Paint.Style.STROKE);//只描边,不填充
        bgPaint.setColor(bgColor);
        bgPaint.setStrokeWidth(barWidth);
        bgPaint.setAntiAlias(true);//设置抗锯齿
        bgPaint.setStrokeCap(Paint.Cap.ROUND);

        progressNum = 0;
        progressSweepAngle = 0;

        mRectF = new RectF();

    }
    public void setNewColor(int colorResourceBG,int colorResourceProgress){
        bgPaint.setColor(getResources().getColor(colorResourceBG));
        progressPaint.setColor(getResources().getColor(colorResourceProgress));

    }

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

        int height = measureSize(defaultSize, heightMeasureSpec);
        int width = measureSize(defaultSize, widthMeasureSpec);
        int min = Math.min(width, height);// 获取View最短边的长度
        setMeasuredDimension(min, min);// 强制改View为以最短边为长度的正方形

        if (min >= barWidth * 2) {//这里简单限制了圆弧的最大宽度
            mRectF.set(barWidth / 2, barWidth / 2, min - barWidth / 2, min - barWidth / 2);
        }

    }

    private int measureSize(int defaultSize, int measureSpec) {
        int result = defaultSize;
        int specMode = View.MeasureSpec.getMode(measureSpec);
        int specSize = View.MeasureSpec.getSize(measureSpec);

        if (specMode == View.MeasureSpec.EXACTLY) {
            result = specSize;
        } else if (specMode == View.MeasureSpec.AT_MOST) {
            result = Math.min(result, specSize);
        }
        return result;
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制 背景弧度
        canvas.drawArc(mRectF, startAngle, sweepAngle, false, bgPaint);
        //绘制 进度弧度
        canvas.drawArc(mRectF, startAngle, progressSweepAngle, false, progressPaint);
    }

    /**
     * 无动画进度
     *
     * @param progressNum
     */
    public void setStaticProgressNum(float progressNum) {

        progressSweepAngle = sweepAngle * progressNum / maxNum;
        invalidate();
    }

    /**
     * 动画绘制进度
     *
     * @param progressNum
     * @param time
     */
    public void setDynamicProgressNum(float progressNum, int time) {

        anim = new CircleBarAnim();
        this.progressNum = progressNum;
        anim.setDuration(time);
        this.startAnimation(anim);
    }


    /**
     * applyTransformation 处理动画变化的过程
     */
    public class CircleBarAnim extends Animation {

        CircleBarAnim() {

        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            super.applyTransformation(interpolatedTime, t);
            //这里计算进度条的比例
            progressSweepAngle = interpolatedTime * sweepAngle * progressNum / maxNum;
            postInvalidate();
        }
    }
}
可以使用CSS3中的transform和animation属性来实现圆环百分比进度的效果,具体步骤如下: 1. 创建一个圆环的基本样式,设置圆环的宽度、颜色和边框样式: ``` .progress { width: 100px; height: 100px; border: 10px solid #eee; border-radius: 50%; position: relative; } .progress:before { content: ""; width: 100%; height: 100%; border-radius: 50%; border: 10px solid #ccc; position: absolute; top: 0; left: 0; } ``` 2. 使用transform属性将圆环旋转90度,使起点从顶部开始: ``` .progress:before { transform: rotate(-90deg); } ``` 3. 使用animation属性设置动画效果,将圆环进度从0%到指定百分比: ``` .progress:after { content: ""; width: 100%; height: 100%; border-radius: 50%; border: 10px solid #000; position: absolute; top: 0; left: 0; transform: rotate(-90deg); animation: progress 2s ease-out forwards; } @keyframes progress { from { transform: rotate(-90deg); } to { transform: rotate(calc(-90deg + (360 * 80 / 100))); } } ``` 其中,animation属性中的forwards参数表示动画结束后保持最后一帧状态,calc函数用来计算旋转角度。 4. 在HTML中添加进度条的容器,并设置对应的百分比: ``` <div class="progress" data-progress="80"></div> ``` 5. 使用JavaScript获取进度条容器和其对应的百分比,将百分比值设置为圆环进度: ``` const progress = document.querySelector('.progress'); const percent = progress.getAttribute('data-progress'); progress.style.setProperty('--progress', `${percent}%`); ``` 6. 最后,在CSS中使用var函数获取JavaScript设置的进度值,并将其应用到圆环进度样式中: ``` .progress:after { transform: rotate(calc(-90deg + (360 * var(--progress) / 100))); } ``` 这样就可以实现一个简单圆环百分比进度条。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值