Android,自定义view,进度条

Android,这种样式的进度条如何画呢?网上找到的都是普普通通的进度条。

img

有一个差不多的 可以修改一下

public class MyRoundView  extends View {


    private Paint circleBgPaint;
    private int mProgress=0,tempProgress = 0;
    Handler handler=new Handler(Looper.getMainLooper());
    private Paint circlePaint;
    private Paint textPaint;
    /*总的进度*/
    private int totalProgress=500;
    /*进度文字距离顶部的距离*/
    private int textTopMargin=30;
    /*圆环的宽度*/
    private float circleBorderWidth;
    /*圆环的背景色*/
    private int circleBgColor;
    /*圆环的颜色*/
    private int circleColor;
    /*设置圆心文字*/
    private String centerTextTop="";
    private String centerTextBottom="";
    private String textBottom="";
    private Rect rect;
    private Paint centerTextTopPaint;
    private Paint centerTextBottomPaint;
    private Typeface tfBottom;
    private Context context;
    /*默认的圆弧的线宽,单位为dp*/
    private final int DEFULT_CIRCLE_BORDER_WIDTH=10;

    public MyRoundView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context=context;

        initAttrs(context,attrs);
        init();
    }

    public MyRoundView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context=context;

        initAttrs(context,attrs);
        init();
    }

    public MyRoundView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        this.context=context;

        initAttrs(context,attrs);
        init();
    }

    private void initAttrs(Context context, @Nullable AttributeSet attrs){
        TypedArray mTypeArray=context.obtainStyledAttributes(attrs, R.styleable.MyRoundView);
        circleBorderWidth=mTypeArray.getDimension(R.styleable.MyRoundView_circleBorderWidth, dp2px(DEFULT_CIRCLE_BORDER_WIDTH));
        circleBgColor=mTypeArray.getColor(R.styleable.MyRoundView_circleBgColor, getResources().getColor(R.color.main_color_light));
        circleColor=mTypeArray.getColor(R.styleable.MyRoundView_circleColor, getResources().getColor(R.color.white));

        mTypeArray.recycle();
    }

    private void init(){
        /*初始化圆弧底部背景画笔*/
        circleBgPaint = new Paint();
        circleBgPaint.setStyle(Paint.Style.STROKE);
        circleBgPaint.setStrokeWidth(circleBorderWidth);
        circleBgPaint.setAntiAlias(true);
        circleBgPaint.setColor(circleBgColor);
        circleBgPaint.setStrokeCap(Paint.Cap.ROUND);

        /*初始化圆弧画笔*/
        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setStyle(Paint.Style.STROKE);
        circlePaint.setStrokeWidth(circleBorderWidth);
        circlePaint.setColor(circleColor);
        circlePaint.setStrokeCap(Paint.Cap.ROUND);

        /*初始化文字画笔*/
        textPaint = new Paint();
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setAntiAlias(true);
        textPaint.setTextSize(40);
        textPaint.setColor(Color.WHITE);

        /*初始化圆心文字画笔*/
        centerTextTopPaint = new Paint();
        centerTextTopPaint.setStyle(Paint.Style.FILL);
        centerTextTopPaint.setAntiAlias(true);
        centerTextTopPaint.setTextSize(35);
        centerTextTopPaint.setColor(Color.WHITE);

        centerTextBottomPaint = new Paint( Paint.ANTI_ALIAS_FLAG);//Paint.FAKE_BOLD_TEXT_FLAG |
        centerTextBottomPaint.setStyle(Paint.Style.FILL);
        centerTextBottomPaint.setAntiAlias(true);
        centerTextBottomPaint.setTextSize(120);
        centerTextBottomPaint.setColor(Color.WHITE);
        tfBottom = Typeface.createFromAsset(context.getAssets(), "fonts/home_weather.ttf");
        centerTextBottomPaint.setTypeface(tfBottom);
        rect = new Rect();


    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int finalWidth=getFinalWidth(widthMeasureSpec);
        int finalHeight=getFinalHeigh(heightMeasureSpec);
        setMeasuredDimension(finalWidth,finalHeight);
    }

    /**
     * 测量View的宽度
     * @param widthMeasureSpec
     * @return
     */
    private int getFinalWidth(int widthMeasureSpec){
        int mode=MeasureSpec.getMode(widthMeasureSpec);
        int size=MeasureSpec.getSize(widthMeasureSpec);
        if (mode==MeasureSpec.AT_MOST){
            size=0;
        }
        return size;
    }

    /**
     * 测量View的高度
     * @param heightMeasureSpec
     * @return
     */
    private int getFinalHeigh(int heightMeasureSpec){
        int mode=MeasureSpec.getMode(heightMeasureSpec);
        int size=MeasureSpec.getSize(heightMeasureSpec);
        if (mode==MeasureSpec.AT_MOST){
            size=0;
        }
        return size;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int minValue=getMeasuredWidth()<getMeasuredHeight()?getMeasuredWidth():getMeasuredHeight();
        float radius=minValue/2-circleBorderWidth/2;

        /*画圆弧背景*/
        canvas.drawArc(circleBorderWidth/2,circleBorderWidth/2,circleBorderWidth/2+2*radius,circleBorderWidth/2+2*radius,135,270,false,circleBgPaint);
        /*画圆弧*/
        canvas.drawArc(circleBorderWidth/2,circleBorderWidth/2,circleBorderWidth/2+2*radius,circleBorderWidth/2+2*radius,135,270*tempProgress/totalProgress,false,circlePaint);
        /*画当前进度文字*/
        canvas.save();
        canvas.translate(circleBorderWidth/2+radius,circleBorderWidth/2+radius);
        String currentProgressStr=textBottom;
        rect.setEmpty();
        textPaint.getTextBounds(currentProgressStr,0,currentProgressStr.length(),rect);
        textPaint.setTypeface(tfBottom);
//        float x1= (float) (-radius*Math.cos(Math.PI*45/180f));
        float y1= (float) (radius*Math.sin(Math.PI*45/180f));

        float X1=-(rect.width()>>1);
        float Y1=y1+(rect.height()>>1)+textTopMargin;
        canvas.drawText(currentProgressStr, X1, Y1, textPaint);

        /**
         * 中央文字
         */
        String centerTextStrTop=centerTextTop;
        rect.setEmpty();
        centerTextTopPaint.getTextBounds(centerTextStrTop,0,centerTextStrTop.length(),rect);
        float X2=-(rect.width()>>1)-5;
        float Y2=(rect.height()>>1)-50;
        canvas.drawText(centerTextStrTop, X2, Y2, centerTextTopPaint);

        String centerTextStrBottom="";
        if (TextUtils.isEmpty(centerTextBottom)){
            centerTextStrBottom=mProgress*100/totalProgress+"%";
        }else{
            centerTextStrBottom=centerTextBottom;
        }
        rect.setEmpty();
        centerTextBottomPaint.getTextBounds(centerTextStrBottom,0,centerTextStrBottom.length(),rect);
        float X3=-(rect.width()>>1)-6;
        float Y3=(rect.height()>>1) + 35;
        canvas.drawText(centerTextStrBottom, X3, Y3, centerTextBottomPaint);

        canvas.restore();
        //动画控制
        if (tempProgress<mProgress){
            if (mProgress<=totalProgress * 1/3){
                tempProgress+=1;
            }else if(mProgress<=totalProgress * 2/3){
                tempProgress+=2;
            }else {
                tempProgress+=3;
            }
            invalidate();
        }else {
            tempProgress = 0;
        }
    }
    public int dp2px(float dpValue) {
        final float scale = getContext().getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }
    public void setProgress(int progress){
        this.mProgress=progress;
        invalidate();
    }
    public void setTotalProgress(int totalProgress){
        this.totalProgress = totalProgress;
        invalidate();
    }
    public void setData(int totalProgress,int progress,String cenTextTop,String cenTextBottom,String textBottom){
        this.totalProgress = totalProgress;
        if (progress>totalProgress){
            this.mProgress = totalProgress;
        }else {
            this.mProgress = progress;
        }
        this.centerTextTop = cenTextTop;
        this.centerTextBottom = cenTextBottom;
        this.textBottom = textBottom;
        invalidate();
    }

styles文件


<!--MyRoundView用到的属性-->
    <declare-styleable name="MyRoundView">
        <attr name="circleBorderWidth" format="dimension"></attr>
        <attr name="circleBgColor" format="color"></attr>
        <attr name="circleColor" format="color"></attr>

布局中正常调用

img

然后 调用代码更新布局

myRoundView.setData(300, Integer.parseInt(weatherBean.getAqi()),
                        "AQI", weatherBean.getAqi(), "空气质量"+weatherBean.getCategory());