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

Android 进度条按钮ProgressButton的实现代码

程序员文章站 2022-06-04 12:20:24
有些app在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生button,重写ondraw来实现带进度条的按钮。 github:https://github...

有些app在点击下载按钮的时候,可以在按钮上显示进度,我们可以通过继承原生button,重写ondraw来实现带进度条的按钮。

github:https://github.com/imcloudfloating/progressbar

1.效果:

Android 进度条按钮ProgressButton的实现代码

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的实现代码,希望对大家有所帮助