有些App在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生Button,重写onDraw来实现带进度条的按钮。
Github:https://github.com/imcloudfloating/ProgressBar
1.效果:
2.原理:
创建三个GradientDrawable作为按钮背景、进度条背景和进度条前景,通过计算进度条的百分比来设置宽度,然后调用invalidate()重绘。GradientDrawable设置颜色、圆角等参数,当然你也可以直接加载xml作为背景。
3.自定义参数:
在values目录建一个attrs.xml文件
1 <?xml version="1.0" encoding="utf-8"?> 2 <resources> 3 4 <attr name="progressColor" format="color" /> 5 <attr name="progressBackColor" format="color" /> 6 <attr name="progress" format="integer" /> 7 <attr name="minProgress" format="integer" /> 8 <attr name="maxProgress" format="integer" /> 9 10 <declare-styleable name="ProgressButton"> 11 <attr name="progressColor" /> 12 <attr name="progressBackColor" /> 13 <attr name="buttonColor" format="color" /> 14 <attr name="cornerRadius" format="dimension" /> 15 <attr name="progress" /> 16 <attr name="minProgress" /> 17 <attr name="maxProgress" /> 18 <attr name="progressMargin" format="dimension" /> 19 </declare-styleable> 20 21 </resources>
3.按钮类:
在setProgress方法中改变mProgress的值,然后调用invalidate()重绘,因为我这里定义了一个minProgress(默认为0),所以在计算进度条宽度的时候,当前进度和最大进度都要先减去minProgress再做除法。
if (progressWidth < mCornerRadius * 2) {
progressWidth = mCornerRadius * 2;
}
当进度条宽度小于2倍圆角半径的时候,进度条的圆角就和背景的圆角不一致,所以加上了上面这段代码。
获取宽度和高度其实用getWidth()和getHeight()也可以,只不过在设计器中没法看到效果,所以我用了getMeasuredWidth()和getMeasuredHeight()。
1 package com.cloud.customviews; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.graphics.Canvas; 6 import android.graphics.drawable.GradientDrawable; 7 import android.support.v7.widget.AppCompatButton; 8 import android.util.AttributeSet; 9 10 public class ProgressButton extends AppCompatButton { 11 12 private float mCornerRadius = 0; 13 private float mProgressMargin = 0; 14 15 private boolean mFinish; 16 17 private int mProgress; 18 private int mMaxProgress = 100; 19 private int mMinProgress = 0; 20 21 private GradientDrawable mDrawableButton; 22 private GradientDrawable mDrawableProgressBackground; 23 private GradientDrawable mDrawableProgress; 24 25 public ProgressButton(Context context, AttributeSet attrs) { 26 super(context, attrs); 27 initialize(context, attrs); 28 } 29 30 public ProgressButton(Context context, AttributeSet attrs, int defStyle) { 31 super(context, attrs, defStyle); 32 initialize(context, attrs); 33 } 34 35 private void initialize(Context context, AttributeSet attrs) { 36 //Progress background drawable 37 mDrawableProgressBackground = new GradientDrawable(); 38 //Progress drawable 39 mDrawableProgress = new GradientDrawable(); 40 //Normal drawable 41 mDrawableButton = new GradientDrawable(); 42 43 //Get default normal color 44 int defaultButtonColor = getResources().getColor(R.color.colorGray, null); 45 //Get default progress color 46 int defaul