上一篇文章总结了下自定义View的几个步骤,如果还有不清楚的同学可以先去看看Android自定义View(一) ,这篇文章和大家分享一下自定义加载进度条,效果如下
下面就以水平的进度条为列进行讲解:
1.首先还是在attrs.xml文件中自定义我们需要的属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<? xml version = "1.0" encoding = "utf-8" ?>
< resources >
< declare-styleable name = "GradientProgressBar" >
< attr name = "textSize" format = "dimension" />
< attr name = "textColor" format = "color" />
< attr name = "bgColor" format = "color" />
< attr name = "startColor" format = "color" />
< attr name = "endColor" format = "color" />
< attr name = "rectRadius" format = "dimension" />
< attr name = "loadSpeed" format = "integer" />
< attr name = "lineWidth" format = "dimension" />
</ declare-styleable >
< declare-styleable name = "RoundProgressBar" >
< attr name = "textSizeRound" format = "dimension" />
< attr name = "textColorRound" format = "color" />
< attr name = "bgColorRound" format = "color" />
< attr name = "currentColorRound" format = "color" />
< attr name = "circleWidthRound" format = "dimension" />
< attr name = "loadSpeedRound" format = "integer" />
</ declare-styleable >
</ resources >
|
2.获取我们的自定义属性:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
/**
* 字体大小
*/
private int mTextSize;
/**
* 字体颜色
*/
private int mTextColor;
/**
* 渐变开始的颜色
*/
private int mStartColor;
/**
* 渐变结束的颜色
*/
private int mEndColor;
/**
* 进度条的宽
*/
private int mProgressWidth;
/**
* 进度条的圆角大小
*/
private int mRadius;
/**
* 默认进度条的颜色
*/
private int mBgColor;
/**
* 进度条的当前进度
*/
private float mCurrentProgress;
/**
* 加载的速度
*/
private int mLoadSpeed;
private String mContent= "0%" ;
private Rect mBounds;
private Paint mPaint;
public GradientProgressBar(Context context) {
this (context, null );
}
public GradientProgressBar(Context context, AttributeSet attrs) {
this (context, attrs, 0 );
}
public GradientProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super (context, attrs, defStyleAttr);
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.GradientProgressBar, defStyleAttr, 0 );
int count = array.getIndexCount();
for ( int i = 0 ; i < count; i++) {
int index = array.getIndex(i);
switch (index) {
case R.styleable.GradientProgressBar_textSize:
/**
* 默认设置为16sp,TypeValue也可以把sp转化为px
*/
mTextSize = array.getDimensionPixelSize(index, ( int ) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16 , getResources().getDisplayMetrics()));
break ;
case R.styleable.GradientProgressBar_textColor:
/**
* 默认设置为黑色
*/
mTextColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.GradientProgressBar_startColor:
mStartColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.GradientProgressBar_endColor:
mEndColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.GradientProgressBar_bgColor:
mBgColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.GradientProgressBar_rectRadius:
mRadius = array.getDimensionPixelSize(index, ( int ) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 10 , getResources().getDisplayMetrics()
));
break ;
case R.styleable.GradientProgressBar_lineWidth:
mProgressWidth=array.getDimensionPixelSize(index,( int )TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 200 ,getResources().getDisplayMetrics()));
break ;
case R.styleable.GradientProgressBar_loadSpeed:
mLoadSpeed=array.getInt(index, 10 );
break ;
}
}
array.recycle();
init();
}
|
init()方法做如下操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private void init(){
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setAntiAlias( true );
mBounds = new Rect();
new Thread( new Runnable() {
@Override
public void run() {
while (mCurrentProgress < mProgressWidth) {
mCurrentProgress = mCurrentProgress + 1 ;
mContent = Math.round((mCurrentProgress / mProgressWidth) * 100 ) + "%" ;
try {
postInvalidate();
Thread.sleep(mLoadSpeed);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
|
3.重写OnDraw()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
@Override
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
/**
* 设置画笔的属性
*/
mPaint.setColor(mBgColor);
mPaint.setStyle(Paint.Style.FILL);
/**
* 绘制背景圆角矩形
*/
canvas.drawRoundRect( 0 , 0 , mProgressWidth, getHeight(), mRadius, mRadius, mPaint);
/**
* 设置线性渐变,设置渐变开始的起点坐标和终点坐标,渐变开始和结束的颜色,设置镜像
* 对于这个方法不太明白的可以google一下,这里不再详细说明
*/
LinearGradient gradient = new LinearGradient( 0 , getHeight() / 2 , mProgressWidth, getHeight() / 2 ,
mStartColor, mEndColor, Shader.TileMode.MIRROR);
mPaint.setShader(gradient);
/**
* 根据进度绘制圆角矩形
*/
canvas.drawRoundRect( 0 , 0 , mCurrentProgress, getHeight(), mRadius, mRadius, mPaint);
mPaint.reset();
mPaint.setAntiAlias( true );
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
/**
* 获取绘制文本所需的矩形大小
*/
mPaint.getTextBounds(mContent, 0 , mContent.length(), mBounds);
canvas.drawText(mContent, getWidth() / 2 - mBounds.width() / 2 , getHeight() / 2 + mBounds.height() / 2 , mPaint);
}
|
好了,这样就完成了我们水平渐变加载进度条,下面贴出圆形进度条的源码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
public class RoundProgressBar extends View {
/**
* 自定义变量
*/
private int mTextSize;
private int mTextColor;
private int mCircleWidth;
private int mBgColor;
private int mCurrentColor;
private int mLoadSpeed;
private float mCurrentProgress;
private String mContent = "0%" ;
private Rect mBounds;
private Paint mPaint;
public RoundProgressBar(Context context) {
this (context, null );
}
public RoundProgressBar(Context context, AttributeSet attrs) {
this (context, attrs, 0 );
}
public RoundProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super (context, attrs, defStyleAttr);
TypedArray array = context.getTheme().obtainStyledAttributes(attrs, R.styleable.RoundProgressBar, defStyleAttr, 0 );
int count = array.getIndexCount();
for ( int i = 0 ; i < count; i++) {
int index = array.getIndex(i);
switch (index) {
case R.styleable.RoundProgressBar_textSizeRound:
/**
* 默认设置为16sp,TypeValue也可以把sp转化为px
*/
mTextSize = array.getDimensionPixelSize(index, ( int ) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 16 , getResources().getDisplayMetrics()));
break ;
case R.styleable.RoundProgressBar_textColorRound:
/**
* 默认设置为黑色
*/
mTextColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.RoundProgressBar_bgColorRound:
mBgColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.RoundProgressBar_circleWidthRound:
mCircleWidth = array.getDimensionPixelSize(index, ( int ) TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, 1 , getResources().getDisplayMetrics()
));
break ;
case R.styleable.RoundProgressBar_currentColorRound:
mCurrentColor = array.getColor(index, Color.BLACK);
break ;
case R.styleable.RoundProgressBar_loadSpeedRound:
mLoadSpeed=array.getInt(index, 10 );
break ;
}
}
array.recycle();
init();
}
private void init() {
mBounds = new Rect();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setAntiAlias( true );
new Thread( new Runnable() {
@Override
public void run() {
while (mCurrentProgress < 360 ) {
mCurrentProgress = mCurrentProgress + 1 ;
mContent = Math.round((mCurrentProgress / 360 ) * 100 ) + "%" ;
postInvalidate();
try {
Thread.sleep(mLoadSpeed);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
protected void onDraw(Canvas canvas) {
super .onDraw(canvas);
/**
* 设置画笔的属性
*/
mPaint.setColor(mBgColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(mCircleWidth);
/**
* 绘制圆环背景
*/
int xPoint = getWidth() / 2 ; //获取圆心x的坐标
int radius = xPoint - mCircleWidth; //获取圆心的半径
canvas.drawCircle(xPoint, xPoint, radius, mPaint); //用于定义的圆弧的形状和大小的界限
/**
* 绘制圆环
*/
mPaint.setColor(mCurrentColor);
RectF oval = new RectF(xPoint - radius, xPoint - radius, radius + xPoint, radius + xPoint);
canvas.drawArc(oval, - 90 , mCurrentProgress, false , mPaint);
/**
* 绘制当前进度文本
*/
mPaint.reset();
mPaint.setAntiAlias( true );
mPaint.setColor(mTextColor);
mPaint.setTextSize(mTextSize);
mPaint.getTextBounds(mContent, 0 , mContent.length(), mBounds);
canvas.drawText(mContent, xPoint - mBounds.width() / 2 , xPoint + mBounds.height() / 2 , mPaint);
}
}
|
4.在xml文件中申明我们的自定义View
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
<? xml version = "1.0" encoding = "utf-8" ?>
< LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android"
xmlns:app = "http://schemas.android.com/apk/res-auto"
android:layout_width = "match_parent"
android:layout_height = "match_parent"
android:background = "@android:color/white"
android:gravity = "center_horizontal"
android:orientation = "vertical" >
< com.customeview2.GradientProgressBar
android:id = "@+id/gradientProgressBar"
android:layout_width = "300dp"
android:layout_height = "15dp"
android:layout_marginLeft = "10dp"
android:layout_marginRight = "10dp"
android:layout_marginTop = "200dp"
app:bgColor = "#C3C3C3"
app:endColor = "#25B7FA"
app:lineWidth = "300dp"
app:loadSpeed = "10"
app:rectRadius = "20dp"
app:startColor = "#D2EEFB"
app:textColor = "@android:color/holo_red_light"
app:textSize = "12sp" />
< com.customeview2.RoundProgressBar
android:id = "@+id/roundProgressBar"
android:layout_width = "60dp"
android:layout_height = "60dp"
android:layout_below = "@+id/gradientProgressBar"
android:layout_gravity = "center"
android:layout_marginLeft = "10dp"
android:layout_marginRight = "10dp"
android:layout_marginTop = "40dp"
app:bgColorRound = "#C3C3C3"
app:circleWidthRound = "3dp"
app:currentColorRound = "#25B7FA"
app:loadSpeedRound = "10"
app:textColor = "@android:color/holo_red_light"
app:textColorRound = "@android:color/holo_red_light"
app:textSizeRound = "11sp" />
</ LinearLayout >
|
好了,这样就完成了我们的水平加载进度条,和圆形加载进度条效果了,是不是感觉还可以啊。
源码下载地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_15192113/article/details/73195665