欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自定义圆环进度条

程序员文章站 2024-02-06 22:55:28
...

首先我们看下我们的效果图

自定义圆环进度条

首先分析下原理

自定义圆环进度条

第一种方式

public class RoundProgress extends View {
private int width;
//设置绘制的圆环及文本的属性---->使用自定义属性替换
private int roundColor = Color.GRAY;//圆环的颜色
private int roundProgressColor = Color.RED;//圆弧的颜色
private int textColor = Color.BLUE;//文本的颜色

private int roundWidth = UIUtils.dp2px(10);//圆环的宽度
private int textSize = UIUtils.dp2px(20);//文本的字体大小

private int max = 100;//圆环的最大值
private int progress = 60;//圆环的进度
private Paint paint;

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

public RoundProgress(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
}

public RoundProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    paint = new Paint();
    paint.setAntiAlias(true);

}

/**
 * 测量:获取当前视图的宽和高
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = this.getMeasuredWidth();
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //1.绘制圆环
    int cx = width / 2;
    int cy = width / 2;
    float radius = width / 2 - roundWidth / 2;
    paint.setColor(roundColor);//设置画笔颜色
    paint.setStyle(Paint.Style.STROKE);//设置圆环的样式
    paint.setStrokeWidth(roundWidth);//设置圆环的宽度
    canvas.drawCircle(cx, cy, radius, paint);
    //2.绘制圆弧
    RectF rectf = new RectF(roundWidth / 2, roundWidth / 2
            , width - roundWidth / 2, width - roundWidth / 2);
    paint.setColor(roundProgressColor);
    canvas.drawArc(rectf, 0, progress* 360 / max , false, paint);
    //3.绘制文字
    String text = progress* 100 / max  + "%";
    //设置paint
    paint.setColor(textColor);
    paint.setStrokeWidth(0);
    paint.setTextSize(textSize);

    Rect rect = new Rect();
    paint.getTextBounds(text, 0, text.length(), rect);//创建了一个矩形,此时矩形没有具体的宽度和高度
    //获取左下顶点的坐标
    float x = width / 2 - rect.width() / 2;
    float y = width / 2 + rect.height() / 2;
    canvas.drawText(text, x, y, paint);
}
}

第二种方式

布局

        <com.hbwj.p2pinvest.ui.RoundProgress
            android:id="@+id/roundPro_home"
            android:layout_width="120dp"
            android:layout_height="120dp"
            android:layout_marginTop="10dp"
            yijia:roundColor="@color/more_text"
            yijia:roundProgressColor="@color/round_red_common"
            yijia:textColor="@color/title_back"
            yijia:textSize="20dp"
            yijia:roundWidth="10dp"
            yijia:max="100"
            yijia:progress="0"/>

自定义属性

 <?xml version="1.0" encoding="utf-8"?>
 <resources>


<declare-styleable name="RoundProgress">
    <attr name="roundColor" format="color" />
    <attr name="roundProgressColor" format="color" />
    <attr name="textColor" format="color" />
    <attr name="roundWidth" format="dimension" />
    <attr name="textSize" format="dimension" />
    <attr name="max" format="integer" />
    <attr name="progress" format="integer" />

</declare-styleable>

</resources>

自定义圆环

public class RoundProgress extends View {
//设置绘制的圆环及文本的属性---->使用自定义属性替换
//private int roundColor = Color.GRAY;//圆环的颜色
//private int roundProgressColor = Color.RED;//圆弧的颜色
//private int textColor = Color.BLUE;//文本的颜色
//private int roundWidth = UIUtils.dp2px(10);//圆环的宽度
// private int textSize = UIUtils.dp2px(20);//文本的字体大小
//private int max = 100;//圆环的最大值
//private int progress = 60;//圆环的进度
//使用自定义属性来初始化如下的变量
private int roundColor;//圆环的颜色
private int roundProgressColor;//圆弧的颜色
private int textColor;//文本的颜色

private float roundWidth;//圆环的宽度
private float textSize;//文本的字体大小

private int max;//圆环的最大值
private int progress;//圆环的进度

private int width;//当前视图的宽度(=高度)

private Paint paint;//画笔

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

public RoundProgress(Context context, @Nullable AttributeSet attrs) {
    this(context, attrs, 0);
}

public RoundProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    //初始化画笔
    paint = new Paint();
    paint.setAntiAlias(true);

    //获取自定义的属性
    //1.获取TypeArray的对象(调用两个参数的方法)
    TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.RoundProgress);

    //2.取出所有的自定义属性
    roundColor = typedArray.getColor(R.styleable.RoundProgress_roundColor, Color.GRAY);
    roundProgressColor = typedArray.getColor(R.styleable.RoundProgress_roundProgressColor, Color.RED);
    textColor = typedArray.getColor(R.styleable.RoundProgress_textColor, Color.GREEN);
    roundWidth = typedArray.getDimension(R.styleable.RoundProgress_roundWidth, UIUtils.dp2px(10));
    textSize = typedArray.getDimension(R.styleable.RoundProgress_textSize, UIUtils.dp2px(20));
    max = typedArray.getInteger(R.styleable.RoundProgress_max, 100);
    progress = typedArray.getInteger(R.styleable.RoundProgress_progress, 30);

    //3.回收处理
    typedArray.recycle();
}

public void setMax(int max) {
    this.max = max;
}

public void setProgress(int progress) {
    this.progress = progress;
}

/**
 * 测量:获取当前视图的宽和高
 */
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width = this.getMeasuredWidth();
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    //1.绘制圆环
    int cx = width / 2;
    int cy = width / 2;
    float radius = width / 2 - roundWidth / 2;
    paint.setColor(roundColor);//设置画笔颜色
    paint.setStyle(Paint.Style.STROKE);//设置圆环的样式
    paint.setStrokeWidth(roundWidth);//设置圆环的宽度
    canvas.drawCircle(cx, cy, radius, paint);
    //2.绘制圆弧
    RectF rectf = new RectF(roundWidth / 2, roundWidth / 2
            , width - roundWidth / 2, width - roundWidth / 2);
    paint.setColor(roundProgressColor);
    canvas.drawArc(rectf, 0, progress * 360 / max, false, paint);
    //3.绘制文字
    String text = progress * 100 / max + "%";
    //设置paint
    paint.setColor(textColor);
    paint.setStrokeWidth(0);
    paint.setTextSize(textSize);

    Rect rect = new Rect();
    paint.getTextBounds(text, 0, text.length(), rect);//创建了一个矩形,此时矩形没有具体的宽度和高度
    //获取左下顶点的坐标
    float x = width / 2 - rect.width() / 2;
    float y = width / 2 + rect.height() / 2;
    canvas.drawText(text, x, y, paint);
}
}

让圆环动起来

 private Runnable runnable = new Runnable() {
    @Override
    public void run() {
        for (int i = 0; i <90; i++) {
            roundProHome.setProgress(i + 1);
            SystemClock.sleep(20);
            //roundProHome.invalidate();//只有在主线程中可以调用
            roundProHome.postInvalidate();//主线程和子线程中都可以调用
        }
    }
};