欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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.效果:

Android 自定义显示进度条的按钮

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 }