Android 自定义显示进度条的按钮
程序员文章站
2022-07-02 07:54:31
有些App在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生Button,重写onDraw来实现带进度条的按钮。 Github:https://github.com/imcloudfloating/DesignApp 1.效果: 2.原理: 创建三个GradientDrawable作为 ......
有些app在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生button,重写ondraw来实现带进度条的按钮。
github:https://github.com/imcloudfloating/designapp
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 defaultprogresscolor = getresources().getcolor(r.color.colorgreen, null); 47 //get default progress background color 48 int defaultbackcolor = getresources().getcolor(r.color.colorgray, null); 49 50 typedarray attr = context.obtainstyledattributes(attrs, r.styleable.progressbutton); 51 52 try { 53 mprogressmargin = attr.getdimension(r.styleable.progressbutton_progressmargin, mprogressmargin); 54 mcornerradius = attr.getdimension(r.styleable.progressbutton_cornerradius, mcornerradius); 55 //get custom normal color 56 int buttoncolor = attr.getcolor(r.styleable.progressbutton_buttoncolor, defaultbuttoncolor); 57 //set normal color 58 mdrawablebutton.setcolor(buttoncolor); 59 //get custom progress background color 60 int progressbackcolor = attr.getcolor(r.styleable.progressbutton_progressbackcolor, defaultbackcolor); 61 //set progress background drawable color 62 mdrawableprogressbackground.setcolor(progressbackcolor); 63 //get custom progress color 64 int progresscolor = attr.getcolor(r.styleable.progressbutton_progresscolor, defaultprogresscolor); 65 //set progress drawable color 66 mdrawableprogress.setcolor(progresscolor); 67 68 //get default progress 69 mprogress = attr.getinteger(r.styleable.progressbutton_progress, mprogress); 70 //get minimum progress 71 mminprogress = attr.getinteger(r.styleable.progressbutton_minprogress, mminprogress); 72 //get maximize progress 73 mmaxprogress = attr.getinteger(r.styleable.progressbutton_maxprogress, mmaxprogress); 74 75 } finally { 76 attr.recycle(); 77 } 78 79 //set corner radius 80 mdrawablebutton.setcornerradius(mcornerradius); 81 mdrawableprogressbackground.setcornerradius(mcornerradius); 82 mdrawableprogress.setcornerradius(mcornerradius - mprogressmargin); 83 setbackgrounddrawable(mdrawablebutton); 84 85 mfinish = false; 86 } 87 88 @override 89 protected void ondraw(canvas canvas) { 90 if (mprogress > mminprogress && mprogress <= mmaxprogress && !mfinish) { 91 //calculate the width of progress 92 float progresswidth = 93 (float) getmeasuredwidth() * ((float) (mprogress - mminprogress) / mmaxprogress - mminprogress); 94 95 //if progress width less than 2x corner radius, the radius of progress will be wrong 96 if (progresswidth < mcornerradius * 2) { 97 progresswidth = mcornerradius * 2; 98 } 99 100 //set rect of progress 101 mdrawableprogress.setbounds((int) mprogressmargin, (int) mprogressmargin, 102 (int) (progresswidth - mprogressmargin), getmeasuredheight() - (int) mprogressmargin); 103 104 //draw progress 105 mdrawableprogress.draw(canvas); 106 107 if (mprogress == mmaxprogress) { 108 setbackgrounddrawable(mdrawablebutton); 109 mfinish = true; 110 } 111 } 112 super.ondraw(canvas); 113 } 114 115 /** 116 * set current progress 117 */ 118 public void setprogress(int progress) { 119 if (!mfinish) { 120 mprogress = progress; 121 setbackgrounddrawable(mdrawableprogressbackground); 122 invalidate(); 123 } 124 } 125 126 public void setmaxprogress(int maxprogress) { 127 mmaxprogress = maxprogress; 128 } 129 130 public void setminprogress(int minprogress) { 131 mminprogress = minprogress; 132 } 133 134 public void reset() { 135 mfinish = false; 136 mprogress = mminprogress; 137 } 138 }
上一篇: 经典的分页完整程序+注释
下一篇: MySQL 日志初探