Android自定义progressbar(雷达扫描样式进度条)

Android自定义progressbar(雷达扫描样式进度条)

项目中需要用到类似雷达扫描的进度条,因为时间有余,所以打算自己做一个。查阅了网上很多教程和资料,最终的运行结果如下图
Android自定义progressbar(雷达扫描样式进度条)_第1张图片

progressbar属性讲解

outerRoundBorderColor_init 表示外圆边框默认颜色,动图里表示浅灰色
outerRoundBorderColor_cover 表示外圆边框覆盖颜色,动图里表示浅蓝色
innerRoundBorderColor 表示内圆边框颜色,动图里表示浅蓝色
innerRoundColor 表示内圆渐变颜色,动图里表示天蓝色
roundBorderWidth 表示外圆边框宽度
progressTextSize 表示进度条字体大小
progressTextColor 表示进度条字体颜色

代码如下

代码可以直接复制使用

public class MyProgressBar extends View {
    private int outerRoundBorderColor_init =Color.GRAY;
    private int outerRoundBorderColor_cover = Color.BLUE;
    private int innerRoundBorderColor = Color.BLUE;
    private int innerRoundColor=Color.CYAN;
    // 10px
    private int mRoundWidth = 10;
    private float mProgressTextSize = 15;

    private int mProgressTextColor = Color.BLUE;

    private Paint mPaint, mTextPaint;
    private int mMax = 100;
    private int mProgress = 0;

    SweepGradient mSweepGradient;

    private Matrix matrix;



     //旋转的角度

    private int degree = 0;

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

    public MyProgressBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }
    public MyProgressBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // 获取自定义属性
        TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.MyProgressBar);
        outerRoundBorderColor_init = array.getColor(R.styleable.MyProgressBar_outerRoundBorderColor_init, outerRoundBorderColor_init);
        outerRoundBorderColor_cover = array.getColor(R.styleable.MyProgressBar_outerRoundBorderColor_cover, outerRoundBorderColor_cover);
        innerRoundBorderColor = array.getColor(R.styleable.MyProgressBar_innerRoundBorderColor, innerRoundBorderColor);
        innerRoundColor = array.getColor(R.styleable.MyProgressBar_innerRoundColor, innerRoundColor);
        mRoundWidth = (int) array.getDimension(R.styleable.MyProgressBar_roundBorderWidth, dip2px(10));
        mProgressTextSize = array.getDimensionPixelSize(R.styleable.MyProgressBar_progressTextSize,
                sp2px(mProgressTextSize));
        mProgressTextColor = array.getColor(R.styleable.MyProgressBar_progressTextColor, mProgressTextColor);

        array.recycle();

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        matrix = new Matrix();

        mTextPaint = new Paint();
        mTextPaint.setAntiAlias(true);
        mTextPaint.setColor(mProgressTextColor);
        mTextPaint.setTextSize(mProgressTextSize);



    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int width=MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        setMeasuredDimension(Math.min(width,height),Math.min(width,height));
    }

    @Override
    protected void onDraw(Canvas canvas) {

        int mWidth = getWidth();

        //圆形渐变色
        if(mSweepGradient == null){
            mSweepGradient = new SweepGradient(mWidth / 2, mWidth / 2, new int[]{Color.TRANSPARENT,innerRoundColor}, null);
        }

        // 画外圆初始化边框颜色
        int radius = mWidth / 2;
        mPaint.setAntiAlias(true);
        mPaint.setColor(outerRoundBorderColor_init);
        mPaint.setStrokeWidth(mRoundWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(radius,radius,radius-mRoundWidth,mPaint);


        //画内圆边框颜色
        mPaint.setAntiAlias(true);
        mPaint.setColor(innerRoundBorderColor);
        mPaint.setStrokeWidth(5);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawCircle(radius,radius,radius/3+5/2,mPaint);

       //画雷达扫描
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setShader(mSweepGradient);
        canvas.drawCircle(mWidth / 2, mWidth / 2, radius / 3, mPaint);

        //画笔重置
        mPaint.reset();

        //使用Matrix旋转
        mSweepGradient.setLocalMatrix(matrix);
        matrix.setRotate(degree, mWidth / 2, mWidth / 2);
        degree++;
        if (degree > 360) {
            degree = 0;
        }
        postInvalidate();


       //进度为0只有文字
        if (mProgress == 0) {
            // 画进度文字
            String text = mProgress + "%";
            @SuppressLint("DrawAllocation") Rect rect=new Rect();
            mTextPaint.getTextBounds(text,0,text.length(),rect);
            float dx=getWidth()/2-rect.width()/2;
            @SuppressLint("DrawAllocation") Paint.FontMetricsInt fontMetricsInt=new Paint.FontMetricsInt();
            int dy=(fontMetricsInt.bottom - fontMetricsInt.top)/2-fontMetricsInt.bottom;
            float baseLine=getHeight()/2+dy;
            canvas.drawText(text,dx,baseLine,mTextPaint);
            return;
        }

        //画外圆进度边框颜色
        @SuppressLint("DrawAllocation") RectF rectF=new RectF(mRoundWidth,mRoundWidth,
                getWidth()-mRoundWidth,getHeight()-mRoundWidth);
        float percent=(float)mProgress/mMax;
        mPaint.setAntiAlias(true);
        mPaint.setColor(outerRoundBorderColor_cover);
        mPaint.setStrokeWidth(mRoundWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawArc(rectF,-90,360*percent,false,mPaint);


        // 画进度文字
        String text = ((int) (percent * 100)) + "%";
        @SuppressLint("DrawAllocation") Rect rect=new Rect();
        mTextPaint.getTextBounds(text,0,text.length(),rect);
        float dx=getWidth()/2-rect.width()/2;
        @SuppressLint("DrawAllocation") Paint.FontMetricsInt fontMetricsInt=new Paint.FontMetricsInt();
        canvas.drawText(text,dx,getHeight()/7*6,mTextPaint);
    }


    public synchronized void setMax(int max) {
        if (max < 0) {
            max=100;
        }
        this.mMax = max;
    }



    public synchronized void setProgress(int progress) {
        if (progress < 0) {
            progress=0;
        }
        this.mProgress = progress;
        invalidate();
    }

    private int sp2px(float sp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, getResources().getDisplayMetrics());
    }

    private float dip2px(int dip) {
        return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, getResources().getDisplayMetrics());
    }

}

需要在style文件里加入自定义属性

<declare-styleable name="MyProgressBar">
        <attr name="outerRoundBorderColor_init" format="color" />
        <attr name="outerRoundBorderColor_cover" format="color" />
        <attr name="innerRoundBorderColor" format="color" />
        <attr name="innerRoundColor" format="color" />
        <attr name="roundBorderWidth" format="dimension" />
        <attr name="progressTextSize" format="dimension" />
        <attr name="progressTextColor" format="color" />
    </declare-styleable>

使用方法如下

layout文件里

 <views.MyProgressBar
        android:id="@+id/mpb_auth_progress"
        android:layout_width="170dp"
        android:layout_height="170dp"
        android:layout_gravity="center"
        android:layout_marginTop="27dp"
        app:progressTextSize="20sp"
        app:progressTextColor="@color/type_blue1"
        app:roundBorderWidth="8dp"
        app:outerRoundBorderColor_init="@color/back_gray11"
        app:outerRoundBorderColor_cover="@color/type_blue1"
        app:innerRoundBorderColor="@color/type_blue1"
        app:innerRoundColor="@color/skyblue"
        />

activity文件里

  val valueAnimator = ObjectAnimator.ofFloat(0f, 100f)
        valueAnimator.setDuration(8000)
        valueAnimator.addUpdateListener(object : ValueAnimator.AnimatorUpdateListener {
            override fun onAnimationUpdate(animation: ValueAnimator) {
                val currentValue = animation.getAnimatedValue() as Float
             mpb_auth_progress.setProgress(currentValue.toInt())
            }
        })
        valueAnimator.start()

有任何使用问题和建议欢迎反馈,谢谢啦

你可能感兴趣的:(学习之路)