自定义控件之中间带文字的环形进度条,重新onMeasure自适配最小宽高问题

这是一片工作日志记录,用的比较多所以记录下来,免得下次又来写。

绘制过程都是在ondraw方法中执行,思路是首先通过drawCircle画灰色底图,然后通过drawArc画粉色进度条,这中间涉及到这两个api的绘制时候的半径问题,主要是arc弧形与它的外切Rect的重合部分要在半径中去除以达到重合效果。

onMeasure中使用来读取xml中写到的半径,并使用宽高的最小尺寸作为最后的半径,此代码片段具有通用性和借鉴意义,这里特此记录:

@Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        smallSize=width>height?height:width;
        setMeasuredDimension(smallSize,smallSize);

    }

效果如图:

自定义控件之中间带文字的环形进度条,重新onMeasure自适配最小宽高问题_第1张图片

SimpleCycleProgressView.java具体代码如下:
package com.xuganwen.testdrag;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * 文件名 SimpleCycleProgressView
 * 文件描述
 * 作者 徐干稳
 * 创建日期 2020/03/17 16:20
 * 版本 1.0
 */
public class SimpleCycleProgressView extends View {


    private Paint paint;
    private int color = Color.parseColor("#EDEDED");
    private Paint textPaint;

    private String textString = "50";

    private float persent = 0.0f;

    private int smallSize=0;

    public SimpleCycleProgressView(Context context) {
        super(context, null);
    }

    public SimpleCycleProgressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(30);
        paint.setColor(color);
        paint.setStyle(Paint.Style.STROKE);

        textPaint = new Paint();
        textPaint.setAntiAlias(true);
        textPaint.setStrokeWidth(5);
        textPaint.setColor(Color.parseColor("#414141"));
        textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    public SimpleCycleProgressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int width = MeasureSpec.getSize(widthMeasureSpec);
        final int height = MeasureSpec.getSize(heightMeasureSpec);
        smallSize=width>height?height:width;
        setMeasuredDimension(smallSize,smallSize);

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawCircle(smallSize / 2, smallSize / 2, smallSize / 2 - 15, paint);

        RectF rectF = new RectF(15, 15, smallSize - 15, smallSize - 15);
        paint.setColor(Color.parseColor("#EB7F8F"));
        canvas.drawArc(rectF, -90, (float) (persent * 3.6), false, paint);

        textPaint.setTextAlign(Paint.Align.CENTER);
//        paint2.setTypeface(Typeface.defaultFromStyle(Typeface.ITALIC));
        textPaint.setTextSize(smallSize / 8);
        Rect rect = new Rect();
        textPaint.getTextBounds(textString, 0, textString.length(), rect);
        Paint.FontMetricsInt fm = textPaint.getFontMetricsInt();
        int baseLineY = smallSize / 2 + (fm.bottom - fm.top) / 2 - fm.bottom;
        canvas.drawText(textString, smallSize / 2, baseLineY, textPaint);
    }


    public void setColor(String colorString) {
        this.color = Color.parseColor(colorString);
    }


    public void setPersent(float persent) {
        this.persent = persent;
        this.textString = persent+ "%";
    }
}

MainActivity.java代码中控件使用如下:

   progressview = findViewById(R.id.progressview);

        progressview.setPersent(Float.valueOf("76.5"));
        progressview.invalidate();

layout.xml中声明如下:




    

    

    

以上就是此控件的所有代码了,如果大家嫌弃图形比较僵硬的话,大家可以在控件的构造方法中插入动画来时环形进度动起来,这里就不写了,各位看官从代码中获得启发的给个赞呗~

你可能感兴趣的:(移动开发)