一篇简单的自定义progressbar,但是可以为初学者提供很好的思路,样式较为简单,如果需要也可以自己完善
先看看样式
首先分析我们需要用到的自定义属性
1、背景圆环或是圆的颜色
2、当前进度加载的颜色
3、文字颜色
4、文字样式,是“%”或是“分”
5、文字大小
6、当前进度的值
7、是否是饼状图
8、圆环的宽度(其实就是画笔的宽度)
开始自定义view
第一步首先创建一个progressbar集成自view(首先创建它是为了我们在自定义属性时,为自定义属性定义名字)
public class MyProgressBar extends View {
public MyProgressBar(Context context) {
super(context);
}
public MyProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
接下来我们就该去定义属性了,至于自定义属性的步骤我就不说了,直接贴代码
<--其实以下两个属性可以不用枚举来处理,这里纯粹是为了测试用枚举-->
好了自定义属性有了,我们就该去捯饬我们的progressbar了,首先获取自定义属性
private void init(Context context,AttributeSet attrs){
//获取自定义的属性值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyProgressBar);
circle_color = typedArray.getColor(R.styleable.MyProgressBar_circle_color, Color.RED);
circle_progregg_color = typedArray.getColor(R.styleable.MyProgressBar_circle_progress_color, Color.GREEN);
text_color = typedArray.getColor(R.styleable.MyProgressBar_text_color, Color.WHITE);
circle_width = typedArray.getInt(R.styleable.MyProgressBar_circle_width, 20);
text_size = typedArray.getInt(R.styleable.MyProgressBar_text_size, 30);
max_progress = typedArray.getInt(R.styleable.MyProgressBar_max_progress, 180);
is_sector = typedArray.getInt(R.styleable.MyProgressBar_is_sector, 0);//0代表不用扇形表示进度,1代表用扇形表示进度
//1代表用中文"分"表示,2代表用%表示进度,3代表圆内部是空的,不要文字
style = typedArray.getInt(R.styleable.MyProgressBar_style, 3);
//初始化画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
重写onMeasure()方法
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (view_size==0){
int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (wSpecSize!=hSpecSize){
view_size=Math.max(wSpecSize,hSpecSize);
}else
view_size=wSpecSize;
}
setMeasuredDimension(view_size, view_size);
}
接下来我们就可以绘制了,重写onDraw()方法
int centre=getWidth()/2;
int radius=centre-circle_width/2;
paint.setColor(circle_color);
paint.setStrokeWidth(circle_width);
RectF o=new RectF(centre-radius,centre-radius,centre+radius,centre+radius);
if (is_sector==1){
//绘制背景
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(centre,centre,radius,paint);
//绘制当前的进度
paint.setColor(circle_progregg_color);
paint.setStyle(Paint.Style.FILL);
canvas.drawArc(o, 270,max_progress,true,paint);
}else {
//绘制背景
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(centre,centre,radius,paint);
//绘制当前的进度
paint.setColor(circle_progregg_color);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(o, 270,max_progress,false,paint);
}
//绘制文字
paint.setColor(text_color);
paint.setTextSize(text_size);
paint.setStrokeWidth(0);//记得设置画笔的宽度为0,否则文字绘制可能会乱
switch (style){
case FRACTION:
String content=max_progress+"分";
float text_width = paint.measureText(content);
canvas.drawText(content,centre-text_width/2,centre+text_size/2,paint);
break;
case PRECENT:
String content2=max_progress+"%";
float text_width2 = paint.measureText(content2);
canvas.drawText(content2,centre-text_width2/2,centre+text_size/2,paint);
break;
case EMPTY:
break;
}
super.onDraw(canvas);
}
接下来就该为每个属性定义set方法了
/**
* 设置圆环的颜色
* @param circle_color
* @return
*/
public MyProgressBar setCircle_color(int circle_color) {
this.circle_color = circle_color;
return this;
}
/**
* 设置进度条的颜色
* @param circle_progregg_color
* @return
*/
public MyProgressBar setCircle_progregg_color(int circle_progregg_color) {
this.circle_progregg_color = circle_progregg_color;
return this;
}
/**
* 设置text的颜色
* @param text_color
* @return
*/
public MyProgressBar setText_color(int text_color) {
this.text_color = text_color;
return this;
}
/**
* 设置圆环的宽度
* @param circle_width
* @return
*/
public MyProgressBar setCircle_width(int circle_width) {
this.circle_width = circle_width;
return this;
}
/**
* 设置文字的大小
* @param text_size
* @return
*/
public MyProgressBar setText_size(int text_size) {
this.text_size = text_size;
return this;
}
/**
* 设置当前最大的进度
* @param max_progress
* @return
*/
public MyProgressBar setMax_progress(int max_progress) {
this.max_progress = max_progress;
return this;
}
/**
* 设置是否需要用扇形展示
* @param is_sector "1"代表用扇形展示,"0"代表用圆弧展示
* @return
*/
public MyProgressBar setIs_sector(int is_sector) {
this.is_sector = is_sector;
return this;
}
/**
* 设置样式
* @param style "FRACTION或是1"代表用"分"展示,"PRECENT或是2"代表用"%"展示,"EMPTY或是3"代表不需要文字展示
* @return
*/
public MyProgressBar setStyle(int style) {
this.style = style;
return this;
}
/**
* 注意:此方法只用在通过代码new出该自定义view时
* 设置view的大小
* @param viewSize 大小
* @return
*/
public MyProgressBar setViewsize(int viewSize) {
this.view_size = viewSize;
return this;
}
提示如果有人是按照我这里步骤一步一步敲出来的,别忘了在第一个构造器中实例化画笔,因为会在代码创建时调用到
//初始化画笔 paint = new Paint(Paint.ANTI_ALIAS_FLAG);
然后我们就可以在布局文件中或是代码中使用了
1、布局中使用
2、代码中创建
MyProgressBar bar = new MyProgressBar(this);
bar.setCircle_color(Color.RED)//设置进度条的背景色
.setCircle_progregg_color(Color.BLUE)//设置进度的颜色
.setCircle_width(20)//设置圆环的宽度
.setIs_sector(0)//设置是否是饼状图,0代表不是,1代表是
.setMax_progress(150)//设置当前进度值
.setStyle(MyProgressBar.PRECENT)//设置样式,注意如果设置样式为空(MyProgressBar.EMPTY),文字是不会显示的
.setText_color(Color.BLACK)//设置文字的颜色
.setText_size(30)//设置文字的大小
.setViewsize(200);//设置view的大小
((ViewGroup)getWindow().getDecorView().findViewById(R.id.activity_main)).addView(bar);
接下来我把整篇的代码贴出来,attrs中的已经贴过了
package com.example.laer.myapplication;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
/**
* 自定义进度条
* Created by Laer on 2016/10/13.
*/
public class MyProgressBar extends View {
private int circle_color;//圆的颜色
private int circle_progregg_color;//进度条的颜色
private int text_color;//文字的颜色
private int circle_width;//圆的宽度
private int text_size;//文字的大小
private int max_progress;//当前最大进度值
private int is_sector;//是否绘扇形
private Paint paint;
private int style;//进度条显示的样式
public static final int FRACTION=1;//分数表示
public static final int PRECENT=2;//%表示
public static final int EMPTY=3;//不需要文字显示
private int view_size;//自定义view的大小
public MyProgressBar(Context context) {
super(context);
//初始化画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
public MyProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
public MyProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context,attrs);
}
private void init(Context context,AttributeSet attrs){
//获取自定义的属性值
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyProgressBar);
circle_color = typedArray.getColor(R.styleable.MyProgressBar_circle_color, Color.RED);
circle_progregg_color = typedArray.getColor(R.styleable.MyProgressBar_circle_progress_color, Color.GREEN);
text_color = typedArray.getColor(R.styleable.MyProgressBar_text_color, Color.WHITE);
circle_width = typedArray.getInt(R.styleable.MyProgressBar_circle_width, 20);
text_size = typedArray.getInt(R.styleable.MyProgressBar_text_size, 30);
max_progress = typedArray.getInt(R.styleable.MyProgressBar_max_progress, 180);
is_sector = typedArray.getInt(R.styleable.MyProgressBar_is_sector, 0);//0代表不用扇形表示进度,1代表用扇形表示进度
//1代表用中文"分"表示,2代表用%表示进度,3代表圆内部是空的,不要文字
style = typedArray.getInt(R.styleable.MyProgressBar_style, 3);
//初始化画笔
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (view_size==0){
int wSpecSize = MeasureSpec.getSize(widthMeasureSpec);
int hSpecSize = MeasureSpec.getSize(heightMeasureSpec);
if (wSpecSize!=hSpecSize){
view_size=Math.max(wSpecSize,hSpecSize);
}else
view_size=wSpecSize;
}
setMeasuredDimension(view_size, view_size);
}
@Override
protected void onDraw(Canvas canvas) {
int centre=getWidth()/2;
int radius=centre-circle_width/2;
paint.setColor(circle_color);
paint.setStrokeWidth(circle_width);
RectF o=new RectF(centre-radius,centre-radius,centre+radius,centre+radius);
if (is_sector==1){
//绘制背景
paint.setStyle(Paint.Style.FILL_AND_STROKE);
canvas.drawCircle(centre,centre,radius,paint);
//绘制当前的进度
paint.setColor(circle_progregg_color);
paint.setStyle(Paint.Style.FILL);
canvas.drawArc(o, 270,max_progress,true,paint);
}else {
//绘制背景
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(centre,centre,radius,paint);
//绘制当前的进度
paint.setColor(circle_progregg_color);
paint.setStyle(Paint.Style.STROKE);
canvas.drawArc(o, 270,max_progress,false,paint);
}
//绘制文字
paint.setColor(text_color);
paint.setTextSize(text_size);
paint.setStrokeWidth(0);//记得设置画笔的宽度为0,否则文字绘制可能会乱
switch (style){
case FRACTION:
String content=max_progress+"分";
float text_width = paint.measureText(content);
canvas.drawText(content,centre-text_width/2,centre+text_size/2,paint);
break;
case PRECENT:
String content2=max_progress+"%";
float text_width2 = paint.measureText(content2);
canvas.drawText(content2,centre-text_width2/2,centre+text_size/2,paint);
break;
case EMPTY:
break;
}
super.onDraw(canvas);
}
/**
* 设置圆环的颜色
* @param circle_color
* @return
*/
public MyProgressBar setCircle_color(int circle_color) {
this.circle_color = circle_color;
return this;
}
/**
* 设置进度条的颜色
* @param circle_progregg_color
* @return
*/
public MyProgressBar setCircle_progregg_color(int circle_progregg_color) {
this.circle_progregg_color = circle_progregg_color;
return this;
}
/**
* 设置text的颜色
* @param text_color
* @return
*/
public MyProgressBar setText_color(int text_color) {
this.text_color = text_color;
return this;
}
/**
* 设置圆环的宽度
* @param circle_width
* @return
*/
public MyProgressBar setCircle_width(int circle_width) {
this.circle_width = circle_width;
return this;
}
/**
* 设置文字的大小
* @param text_size
* @return
*/
public MyProgressBar setText_size(int text_size) {
this.text_size = text_size;
return this;
}
/**
* 设置当前最大的进度
* @param max_progress
* @return
*/
public MyProgressBar setMax_progress(int max_progress) {
this.max_progress = max_progress;
return this;
}
/**
* 设置是否需要用扇形展示
* @param is_sector "1"代表用扇形展示,"0"代表用圆弧展示
* @return
*/
public MyProgressBar setIs_sector(int is_sector) {
this.is_sector = is_sector;
return this;
}
/**
* 设置样式
* @param style "FRACTION或是1"代表用"分"展示,"PRECENT或是2"代表用"%"展示,"EMPTY或是3"代表不需要文字展示
* @return
*/
public MyProgressBar setStyle(int style) {
this.style = style;
return this;
}
/**
* 注意:此方法只用在通过代码new出该自定义view时
* 设置view的大小
* @param viewSize 大小
* @return
*/
public MyProgressBar setViewsize(int viewSize) {
this.view_size = viewSize;
return this;
}
}