首页 > 代码库 > 自定义圆形进度条

自定义圆形进度条

关于控件呢,我想大家应该都很熟悉了吧,android应用开发MVC架构中,控件担任着至关重要的作用,感觉可以说是基于控件的事件模型人机交互的基础吧。这种特性感觉在wpf开发中体现得更为直接,感兴趣的同学可以去了解一下。而android框架自身就已经给我们提供了很多控件。那么问题来了?为什么有那么多控件可以用,你还要去屑自定义控件呢?是因为大家闲的蛋疼吗?显然不是。个人认为只要有两方面吧,要么是觉得有些原生控件是在是丑得难以忍受(即使是在你已经自定义了他的shape,圆角,selector等一系列style以及annotation之后);还有最容易出现的原因就是原生控件已经难以满足你的需求。
好吧,我承认以上都是废话,可是我刚开始学java和android的时候,记得是大一暑假吧,当时我是真心不理解这些,当时要是有人更我说一下这些,我就不会那么迷茫了。

接下来就让我们来看一下,如何实现一个简单的圆形进度条吧。

首先你需要 extends View类。这样你就可以在需要的Activity或fragment里面引用你的自定义控件。而,圆形进度条的话,你就需要自己按照特定的规律来画圆(例如,倒计时,下载进度)。而extends View后,你需要重载protected void onDraw(Canvas canvas) 方法。之后,你便可以用canvas来会出你想要的形状。这里我们就画圆吧。
而画圆需要用到canvas.drawArc(oval, -90, ((float) progress / maxProgress) * 360, false, paint)方法。这里面第一个参数确定所画圆的范围。第二个参数确定开始画圆的位置,-90是从12点钟方向开始。第三个参数是每次绘制圆弧对应圆心角的度数。最后一个参数是设置画笔paint。
最关键的是第一个参数RectF,由他来确定在什么地方绘制圆弧,因为canvas所绘制的圆弧是由RectF所确定矩形区域的内切圆(尽管矩形并没有绘制出来,但是他真的存在,自行脑补)。RectF有四个参数,具体设置can jain下面的代码。接下来比价重要的就是paint了,你可以对paint设置颜色,线宽,是否抗锯齿等属性。

下面给出代码吧,里面有比较详细的注释。

package com.pocketdigi.curcleprogressbar.view;

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

public class CircleProgressBar extends View {
private int maxProgress = 100;
private int progress = 30;
private int progressStrokeWidth = 4;
//画圆所在的距形区域
RectF oval;
Paint paint;
public CircleProgressBar(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO 自动生成的构造函数存根
    oval = new RectF();
    paint = new Paint();
    }

@Override
protected void onDraw(Canvas canvas) {
    // TODO 自动生成的方法存根
    super.onDraw(canvas);
    int width = this.getWidth();
    int height = this.getHeight();

    if(width!=height)
    {
        int min=Math.min(width, height);
        width=min;
        height=min;
    }

    paint.setAntiAlias(true); // 设置画笔为抗锯齿
    paint.setColor(Color.WHITE); // 设置画笔颜色
    canvas.drawColor(Color.TRANSPARENT); // 白色背景
    paint.setStrokeWidth(progressStrokeWidth); //线宽
    paint.setStyle(Style.STROKE);

    oval.left = progressStrokeWidth / 2; // 左上角x
    oval.top = progressStrokeWidth / 2; // 左上角y
    oval.right = width - progressStrokeWidth / 2; // 左下角x
    oval.bottom = height - progressStrokeWidth / 2; // 右下角y

    canvas.drawArc(oval, -90, 360, false, paint); // 绘制白色圆圈,即进度条背景
    paint.setColor(Color.rgb(0x57, 0x87, 0xb6));
    canvas.drawArc(oval, -90, ((float) progress / maxProgress) * 360, false, paint); // 绘制进度圆弧,这里是蓝色

    paint.setStrokeWidth(1);
    String text = progress + "%";
    int textHeight = height / 4;
    paint.setTextSize(textHeight);
    int textWidth = (int) paint.measureText(text, 0, text.length());
    paint.setStyle(Style.FILL);
    canvas.drawText(text, width / 2 - textWidth / 2, height / 2 +textHeight/2, paint);

}



public int getMaxProgress() {
    return maxProgress;
}

public void setMaxProgress(int maxProgress) {
    this.maxProgress = maxProgress;
}

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

/**
 * 非UI线程调用
 */
public void setProgressNotInUiThread(int progress) {
    this.progress = progress;
    this.postInvalidate();
}
}

下面就看一下如何来使用这个自定义控件吧。首先你需要在相应的XML文件中引用他。

 <wenyue.justdoit.view.CircleProgressBar
 android:id="@+id/circleProgressbar"
 android:layout_width="300dp"
 android:layout_height="300dp"
 android:layout_centerInParent="true" />

然后就是findViewById之类的,此处不再赘述。而当你拿到progressBar实例后,就可以给他设置一些参数,而这些set方法你必须在重写的类中实现它。例如:progressBar.setProgressNotInUiThread(i);
其他的,setOnclickListener之类的按需要设置即可。至此,一个简单的圆形进度条便已经大功告成了。哈哈。

自定义圆形进度条