有些App在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生Button,重写onDraw来实现带进度条的按钮。
Github:https://github.com/imcloudfloating/ProgressBar
1.效果:
2.原理:
创建三个GradientDrawable作为按钮背景、进度条背景和进度条前景,通过计算进度条的百分比来设置宽度,然后调用invalidate()重绘。GradientDrawable设置颜色、圆角等参数,当然你也可以直接加载xml作为背景。
3.自定义参数:
在values目录建一个attrs.xml文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
<?xml version= "." encoding= "utf-" ?> <resources> <attr name= "progressColor" format= "color" /> <attr name= "progressBackColor" format= "color" /> <attr name= "progress" format= "integer" /> <attr name= "minProgress" format= "integer" /> <attr name= "maxProgress" format= "integer" /> <declare-styleable name= "ProgressButton" > <attr name= "progressColor" /> <attr name= "progressBackColor" /> <attr name= "buttonColor" format= "color" /> <attr name= "cornerRadius" format= "dimension" /> <attr name= "progress" /> <attr name= "minProgress" /> <attr name= "maxProgress" /> <attr name= "progressMargin" format= "dimension" /> </declare-styleable> </resources> |
3.按钮类:
在setProgress方法中改变mProgress的值,然后调用invalidate()重绘,因为我这里定义了一个minProgress(默认为0),所以在计算进度条宽度的时候,当前进度和最大进度都要先减去minProgress再做除法。
1
2
3
|
if (progressWidth < mCornerRadius * 2 ) { progressWidth = mCornerRadius * 2 ; } |
当进度条宽度小于2倍圆角半径的时候,进度条的圆角就和背景的圆角不一致,所以加上了上面这段代码。
获取宽度和高度其实用getWidth()和getHeight()也可以,只不过在设计器中没法看到效果,所以我用了getMeasuredWidth()和getMeasuredHeight()。
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
|
package com.cloud.customviews; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.drawable.GradientDrawable; import android.support.v.widget.AppCompatButton; import android.util.AttributeSet; public class ProgressButton extends AppCompatButton { private float mCornerRadius = ; private float mProgressMargin = ; private boolean mFinish; private int mProgress; private int mMaxProgress = ; private int mMinProgress = ; private GradientDrawable mDrawableButton; private GradientDrawable mDrawableProgressBackground; private GradientDrawable mDrawableProgress; public ProgressButton(Context context, AttributeSet attrs) { super (context, attrs); initialize(context, attrs); } public ProgressButton(Context context, AttributeSet attrs, int defStyle) { super (context, attrs, defStyle); initialize(context, attrs); } private void initialize(Context context, AttributeSet attrs) { //Progress background drawable mDrawableProgressBackground = new GradientDrawable(); //Progress drawable mDrawableProgress = new GradientDrawable(); //Normal drawable mDrawableButton = new GradientDrawable(); //Get default normal color int defaultButtonColor = getResources().getColor(R.color.colorGray, null ); //Get default progress color int defaultProgressColor = getResources().getColor(R.color.colorGreen, null ); //Get default progress background color int defaultBackColor = getResources().getColor(R.color.colorGray, null ); TypedArray attr = context.obtainStyledAttributes(attrs, R.styleable.ProgressButton); try { mProgressMargin = attr.getDimension(R.styleable.ProgressButton_progressMargin, mProgressMargin); mCornerRadius = attr.getDimension(R.styleable.ProgressButton_cornerRadius, mCornerRadius); //Get custom normal color int buttonColor = attr.getColor(R.styleable.ProgressButton_buttonColor, defaultButtonColor); //Set normal color mDrawableButton.setColor(buttonColor); //Get custom progress background color int progressBackColor = attr.getColor(R.styleable.ProgressButton_progressBackColor, defaultBackColor); //Set progress background drawable color mDrawableProgressBackground.setColor(progressBackColor); //Get custom progress color int progressColor = attr.getColor(R.styleable.ProgressButton_progressColor, defaultProgressColor); //Set progress drawable color mDrawableProgress.setColor(progressColor); //Get default progress mProgress = attr.getInteger(R.styleable.ProgressButton_progress, mProgress); //Get minimum progress mMinProgress = attr.getInteger(R.styleable.ProgressButton_minProgress, mMinProgress); //Get maximize progress mMaxProgress = attr.getInteger(R.styleable.ProgressButton_maxProgress, mMaxProgress); } finally { attr.recycle(); } //Set corner radius mDrawableButton.setCornerRadius(mCornerRadius); mDrawableProgressBackground.setCornerRadius(mCornerRadius); mDrawableProgress.setCornerRadius(mCornerRadius - mProgressMargin); setBackgroundDrawable(mDrawableButton); mFinish = false ; } @Override protected void onDraw(Canvas canvas) { if (mProgress > mMinProgress && mProgress <= mMaxProgress && !mFinish) { //Calculate the width of progress float progressWidth = ( float ) getMeasuredWidth() * (( float ) (mProgress - mMinProgress) / mMaxProgress - mMinProgress); //If progress width less than x corner radius, the radius of progress will be wrong if (progressWidth < mCornerRadius * ) { progressWidth = mCornerRadius * ; } //Set rect of progress mDrawableProgress.setBounds(( int ) mProgressMargin, ( int ) mProgressMargin, ( int ) (progressWidth - mProgressMargin), getMeasuredHeight() - ( int ) mProgressMargin); //Draw progress mDrawableProgress.draw(canvas); if (mProgress == mMaxProgress) { setBackgroundDrawable(mDrawableButton); mFinish = true ; } } super .onDraw(canvas); } /** * Set current progress */ public void setProgress( int progress) { if (!mFinish) { mProgress = progress; setBackgroundDrawable(mDrawableProgressBackground); invalidate(); } } public void setMaxProgress( int maxProgress) { mMaxProgress = maxProgress; } public void setMinProgress( int minProgress) { mMinProgress = minProgress; } public void reset() { mFinish = false ; mProgress = mMinProgress; } } |
使用:
1
2
3
4
5
6
7
8
9
10
11
12
|
<com.cloud.customviews.ProgressButton android:id= "@+id/button_progress_green" android:layout_width= "dp" android:layout_height= "wrap_content" android:layout_marginTop= "dp" android:textAllCaps= "false" android:textColor= "@color/colorWhite" android:text= "@string/button_progress" app:cornerRadius= "dp" app:progressMargin= "dp" app:progressColor= "@color/colorGreen" app:buttonColor= "@color/colorGreen" /> |
总结
以上所述是小编给大家介绍的Android 进度条按钮ProgressButton的实现代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言小编会及时回复大家的!
原文链接:https://www.cnblogs.com/cloudfloating/archive/2018/10/26/9858305.html