防百度云APP下载列表圆形进度条

博客主要围绕Android开发展开,展示了自定义圆形进度条View的效果图,还提及了相关图片资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图:

自定义view如下:

package tv.buka.android.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ProgressBar;

import tv.buka.android.R;

/**
 * 上传下载的进度---自定义控件
 * <p>
 * Created by hwk on 2019/4/23.
 */
public class CircleProgressBar extends ProgressBar {
    private int mDefaultColor;
    private int mReachedColor;
    private float mDefaultHeight;
    private float mReachedHeight;
    private float mRadius;
    private Paint mPaint;

    private Status mStatus = Status.Waiting;

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

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

    public CircleProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar);
        //默认圆的颜色
        mDefaultColor = typedArray.getColor(R.styleable.CircleProgressBar_defaultColor, Color.parseColor("#EDEDED"));
        //进度条的颜色
        mReachedColor = typedArray.getColor(R.styleable.CircleProgressBar_reachedColor, Color.parseColor("#F74142"));
        //默认圆的高度
        mDefaultHeight = typedArray.getDimension(R.styleable.CircleProgressBar_defaultHeight, dp2px(context, 1f));
        //进度条的高度
        mReachedHeight = typedArray.getDimension(R.styleable.CircleProgressBar_reachedHeight, dp2px(context, 1f));
        //圆的半径
        mRadius = typedArray.getDimension(R.styleable.CircleProgressBar_radius, dp2px(context, 9));
        typedArray.recycle();

        setPaint();
    }

    private void setPaint() {
        mPaint = new Paint();
        //下面是设置画笔的一些属性
        mPaint.setAntiAlias(true);//抗锯齿
        mPaint.setDither(true);//防抖动,绘制出来的图要更加柔和清晰
        mPaint.setStyle(Paint.Style.STROKE);//设置填充样式
        /**
         *  Paint.Style.FILL    :填充内部
         *  Paint.Style.FILL_AND_STROKE  :填充内部和描边
         *  Paint.Style.STROKE  :仅描边
         */
        mPaint.setStrokeCap(Paint.Cap.ROUND);//设置画笔笔刷类型
    }

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

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

        float paintHeight = Math.max(mReachedHeight, mDefaultHeight);//比较两数,取最大值

        if (heightMode != MeasureSpec.EXACTLY) {
            //如果用户没有精确指出宽高时,我们就要测量整个View所需要分配的高度了,测量自定义圆形View设置的上下内边距+圆形view的直径+圆形描边边框的高度
            int exceptHeight = (int) (getPaddingTop() + getPaddingBottom() + mRadius * 2 + paintHeight);
            //然后再将测量后的值作为精确值传给父类,告诉他我需要这么大的空间,你给我分配吧
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(exceptHeight, MeasureSpec.EXACTLY);
        }
        if (widthMode != MeasureSpec.EXACTLY) {
            //这里在自定义属性中没有设置圆形边框的宽度,所以这里直接用高度代替
            int exceptWidth = (int) (getPaddingLeft() + getPaddingRight() + mRadius * 2 + paintHeight);
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(exceptWidth, MeasureSpec.EXACTLY);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected synchronized void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        //为了保证最外层的圆弧全部显示,我们通常会设置自定义view的padding属性,这样就有了内边距,所以画笔应该平移到内边距的位置,这样画笔才会刚好在最外层的圆弧上
        //画笔平移到指定paddingLeft, getPaddingTop()位置
        canvas.translate(getPaddingStart(), getPaddingTop());
        int mDiameter = (int) (mRadius * 2);

        int drawableInt = R.mipmap.ic_waiting;
        switch (mStatus) {
            case Waiting:
                drawableInt = R.mipmap.ic_waiting;
                break;
            case Loading:
                drawableInt = R.mipmap.ic_loading;
                break;
            case Pause_Upload:
                drawableInt = R.mipmap.ic_pause_upload;
                break;
            case Pause_Download:
                drawableInt = R.mipmap.ic_pause_download;
                break;
            case Error:
                drawableInt = R.mipmap.ic_error;
                break;
        }
        Drawable drawable = getContext().getResources().getDrawable(drawableInt);
        drawable.setBounds(0, 0, mDiameter, mDiameter);
        drawable.draw(canvas);

        mPaint.setStyle(Paint.Style.STROKE);
        //画默认圆(边框)的一些设置
        mPaint.setColor(mDefaultColor);
        mPaint.setStrokeWidth(mDefaultHeight);
        canvas.drawCircle(mRadius, mRadius, mRadius, mPaint);

        if (mStatus == Status.Waiting || mStatus == Status.Loading || mStatus == Status.Pause_Download || mStatus == Status.Pause_Upload) {
            //画进度条的一些设置
            mPaint.setColor(mReachedColor);
            mPaint.setStrokeWidth(mReachedHeight);
            //根据进度绘制圆弧
            float sweepAngle = getProgress() * 1.0f / getMax() * 360;
            canvas.drawArc(new RectF(0, 0, mRadius * 2, mRadius * 2), -90, sweepAngle, false, mPaint);
        }
        canvas.restore();
    }

    public Status getStatus() {
        return mStatus;
    }

    public void setStatus(Status status) {
        if (mStatus == status) return;
        mStatus = status;
        invalidate();
    }

    public enum Status {
        Waiting,
        Loading,
        Pause_Upload,
        Pause_Download,
        Error
    }

    float dp2px(Context context, float dp) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return dp * scale + 0.5f;
    }
}

图片资源:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值