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

Android自定义控件制作显示进度的Button

程序员文章站 2024-03-07 15:11:03
最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的button直接显示文件的下载进度,通过改变其背景色,从左向右推进,直到填满整个butt...

最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的button直接显示文件的下载进度,通过改变其背景色,从左向右推进,直到填满整个button时,意味着下载任务的完成。

除了这种效果,还看到某酷的视频客户端,在观看过的视频对应的按钮上,会给该按钮添加一个描边效果,4条边,每条边代表25%的进度,由上沿开始,顺时针最终到左边沿,则代表100%的进度,这种效果也很不错。

自己也研究了一下,写了个自定义的button,下面是效果, 

普通的填充效果: 

Android自定义控件制作显示进度的Button

描边的效果: 

Android自定义控件制作显示进度的Button

自定义button的主要实现就是继承button,并重写ondraw()方法,填充的效果实现起来相对简单一点:

 if(currenttype == type_fill) {
      mpaint.setcolor(getcontext().getresources().getcolor(r.color.green_yellow));
      mpaint.setantialias(true);
      mpaint.setalpha(128);
      mpaint.setstrokewidth(1.0f);
      rect rect = new rect();
      //先获取button的边框
      canvas.getclipbounds(rect);
      rect.left += getpaddingleft();
      //填充条的右边界根据当前进度来计算
      rect.top += getpaddingtop();
      rect.right = (rect.left - getpaddingleft()) + (mprogress * getwidth() / 100) - getpaddingright();
      rect.bottom -= getpaddingbottom();
      //绘制一个圆角的长条,这样相对好看一点
      canvas.drawroundrect(new rectf(rect), 8.0f, 8.0f, mpaint);
    } 
       

描边效果实现起来相对复杂一点,确切说是繁琐:

     else if(currenttype == type_stroke) {
      //初始化画笔
      mpaint.setantialias(true);
      mpaint.setcolor(getcontext().getresources().getcolor(r.color.green_yellow));
      mpaint.setalpha(255);
      //获取button的边框
      rect rect = new rect();
      canvas.getclipbounds(rect);
      paint paint1, paint2, paint3, paint4;
      //根据当前进度,确定是绘制哪条边,其实也是绘制一个矩形,只不过这个矩形比较扁或是比较窄而已,类似一条边
      if(mprogress >= 0 && mprogress < 25) {
        paint1 = new paint(mpaint);
        rect temp = new rect(rect.left + getpaddingleft(),
            rect.top + getpaddingtop(),
            rect.left + mprogress * (getwidth() - getpaddingleft() - getpaddingright())
                / 25 - getpaddingright(),
            rect.top + getpaddingtop() + 2);
        canvas.drawrect(temp, paint1);
      } else if(mprogress < 50) {
        paint1 = new paint(mpaint);
        rect rect1 = new rect(rect.left + getpaddingleft(),
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.top + getpaddingtop() + 2);
        canvas.drawrect(rect1, paint1);

        paint2 = new paint(mpaint);
        rect rect2 = new rect(rect.right - getpaddingright() - 2,
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.top + getpaddingtop() + (mprogress - 25) *
                (getheight() - getpaddingtop() - getpaddingbottom()) / 25);
        canvas.drawrect(rect2, paint2);
      } else if(mprogress < 75) {
        paint1 = new paint(mpaint);
        rect rect1 = new rect(rect.left + getpaddingleft(),
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.top + getpaddingtop() + 2);
        canvas.drawrect(rect1, paint1);

        paint2 = new paint(mpaint);
        rect rect2 = new rect(rect.right - getpaddingright() - 2,
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.bottom - getpaddingbottom());
        canvas.drawrect(rect2, paint2);

        paint3 = new paint(mpaint);
        rect rect3 = new rect(
            rect.right - getpaddingright() - (mprogress - 50) *
                (getwidth() - getpaddingleft() - getpaddingright()) / 25,
            rect.bottom - getpaddingbottom() - 2,
            rect.right - getpaddingright(),
            rect.bottom - getpaddingbottom());
        canvas.drawrect(rect3, paint3);
      } else if(mprogress <= 100) {
        paint1 = new paint(mpaint);
        rect rect1 = new rect(
            rect.left + getpaddingleft(),
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.top + getpaddingtop() + 2);
        canvas.drawrect(rect1, paint1);

        paint2 = new paint(mpaint);
        rect rect2 = new rect(
            rect.right - getpaddingright() - 2,
            rect.top + getpaddingtop(), rect.right - getpaddingright(),
            rect.bottom - getpaddingbottom());
        canvas.drawrect(rect2, paint2);

        paint3 = new paint(mpaint);
        rect rect3 = new rect(
            rect.left + getcompoundpaddingleft(),
            rect.bottom - getpaddingbottom() - 2, rect.right - getpaddingright(),
            rect.bottom - getpaddingright());
        canvas.drawrect(rect3, paint3);

        paint4 = new paint(mpaint);
        rect rect4 = new rect(
            rect.left + getcompoundpaddingleft(),
            rect.bottom - getpaddingbottom() - (mprogress - 75) *
                (getheight() - getpaddingtop() - getpaddingbottom()) / 25,
            rect.left + getpaddingleft() + 2,
            rect.bottom - getpaddingbottom());
        canvas.drawrect(rect4, paint4);
      }
    } 

记得最后执行 super.ondraw(canvas);

这样会让填充或是描边绘制在最底层,不会挡住button原有的内容。

然后添加一个api,用于更新进度: 

  public void updateprogress(int progress) {
    if(progress >= 0 && progress <= 100) {
      mprogress = progress;
      invalidate();
    } else if(progress < 0) {
      mprogress = 0;
      invalidate();
    } else if(progress > 100) {
      mprogress = 100;
      invalidate();
    }
  } 

demo的代码上传到了github上:https://github.com/youngleeforeverboy/progressbutton

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。