Android 进度条按钮ProgressButton的实现代码
程序员文章站
2023-09-04 13:33:43
有些app在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生button,重写ondraw来实现带进度条的按钮。
github:https://github...
有些app在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生button,重写ondraw来实现带进度条的按钮。
github:https://github.com/imcloudfloating/progressbar
1.效果:
2.原理:
创建三个gradientdrawable作为按钮背景、进度条背景和进度条前景,通过计算进度条的百分比来设置宽度,然后调用invalidate()重绘。gradientdrawable设置颜色、圆角等参数,当然你也可以直接加载xml作为背景。
3.自定义参数:
在values目录建一个attrs.xml文件
<?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再做除法。
if (progresswidth < mcornerradius * 2) { progresswidth = mcornerradius * 2; }
当进度条宽度小于2倍圆角半径的时候,进度条的圆角就和背景的圆角不一致,所以加上了上面这段代码。
获取宽度和高度其实用getwidth()和getheight()也可以,只不过在设计器中没法看到效果,所以我用了getmeasuredwidth()和getmeasuredheight()。
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; } }
使用:
<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的实现代码,希望对大家有所帮助
上一篇: 上万VS几千:高中低端电视差距究竟在哪?