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

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

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

自己也研究了一下,写了个自定义的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

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

(0)

相关推荐

  • Android手机开发 使用线性布局和相对布局实现Button垂直水平居中

    居中呢,这里分两种不同布局方式的居中!分别是 LinearLayout 和RelativeLayout. 一.首先说的是LinearLayout布局下的居中: 注意:android:layout_width="fill_parent" android:layout_height="fill_parent" 属性中,若水平居中,至少在宽度上占全屏:若垂直居中,则在高度上占全屏 <LinearLayout android:layout_width="fi

  • Android开发之创建可点击的Button实现方法

    本文实例讲述了Android创建可点击的Button实现方法.分享给大家供大家参考,具体如下: 感觉到自己有必要学习下手机开发方面的知识,不论是为了以后的工作需求还是目前的公司项目. 当然,任何新东西的开始,必然伴随着第一个HelloWorld,Android学习也不例外.既然才开始,我就不做过多的描述了. 对于Android开发的IDE:ADT来说,打开的第一眼有点迷糊,不过看了网上各种目录结构的介绍,慢慢的就明白了,做这个实例,我们尤其需要关注两个地方,一个是src目录,一个就是res目录下

  • Android中button点击后字体的变色效果

    button的点击效果无疑是非常简单的,以致于我懒到当UI告诉我说在点击的时候button字体的颜色也要随着背景改变的时候我毫不犹豫的告诉他让他切两个图过来,后来想想着实是不太靠谱,于是了解了一下如何添加button点击的字体颜色变化效果. 1.首先你要在你的color文件下加入几个你需要的色值,注意不同的是不是一般的color标签,而是drawable标签,就像这样: <drawable name="color_red">#fffa3d39</drawable>

  • Android RadioButton 图片位置与大小实例详解

    Android RadioButton 图片位置与大小 Java: rgGroup = (RadioGroup) findViewById(R.id.re_group); rbWeiHui = (RadioButton) findViewById(R.id.rb_wei_hui); rbAdd = (RadioButton) findViewById(R.id.rb_add); rbMine = (RadioButton) findViewById(R.id.rb_mine); //定义底部标签

  • Android Button按钮的四种点击事件

    本文实例为大家分享了安卓Button按钮的四种点击事件,供大家参考,具体内容如下 第一种:内部类实现 1.xml里面先设置Button属性 <Button android:id="+@id/button1"; android:layout_width="wrap_parent"; android:layout_height="wrap_parent" android:text="按钮"/> 2.找到按钮 Butto

  • Android自定义FloatingActionButton滑动行为只隐藏不出现的问题小结

    先来段Behavior代码,网上关于FloatingActionButton(以下简称FAB)滑动的代码很多了,参考一下. public class FabBehavior extends FloatingActionButton.Behavior{ private static final Interpolator INTERPOLATOR = new FastOutSlowInInterpolator(); private boolean mIsAnimatingOut = false; p

  • Android 自定义Button控件实现按钮点击变色

    效果图如下所示: 一.shape 样式:(在drawable新建-->new-->Drawable resource file 在父级标签selector添加Item ) <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item and

  • Android自定义button点击效果的两种方式

    我们在界面上经常会用到button按钮,但通常button点击后看不到点击的效果,如果用户连续点击了两次,就会报NAR错误,这样交互性就比较差了.如果我们自定义了button点击效果,比如我们点击了button能让我们看到我们确实点击了button按钮,这样就会有效的避免重复点击了. 自定义点击效果有两种方式,一种是在xml中定义,另一种是在代码中定义. 首先看一下如何在xml中定义: 在drawable下新建selector.xml文件: <?xml version="1.0"

  • Android中EditText+Button组合导致输入板无法收起的原因分析及解决办法

    在Android开发中,录入信息是最基本的操作,使用非常广泛. 但是Android对输入法弹出/收起的支持,并不是很好. 对弹出,提供了force方式和implicit方式,对输入却没有提供force方式. 可想而知,想弹能弹,想收不能收,这是多么的痛苦! 没有对输入法做任何处理的情况下,EditText输入后,点击Button一般会自动收起输入法. 若没有收起,那可能是布局上有一些问题,可以尝试在最外层添加scrollView. 笔者亲测在大部分情况下,嵌套scrollView是可行的. 如果

  • Android实现点击Button产生水波纹效果

    先上图,看看接下来我要向大家介绍的是个什么东西,如下图: 接下来要介绍的就是如何实现上述图中的波纹效果,这种效果如果大家没有体验过的话,可以看看百度手机卫士或者360手机卫士,里面的按钮点击效果都是这样的,另外Android 5.0以上的版本也出现了这种效果.不多说,下面聊聊具体的怎么实现. 首先大家看到的是三个button,水波纹的出现给我们的错觉是直接将波纹绘制在button上面的,但是这样能做到吗?首先button自己有background和src,如果把半透明的水波纹当作backgrou

  • Android编程实现长按Button按钮连续响应功能示例

    本文实例讲述了Android编程实现长按Button按钮连续响应功能.分享给大家供大家参考,具体如下: 在电商类app的购物车页面,经常会有这样的需求:长按"+"按钮或者"-"按钮时,购物车中的商品数量连续的增加或减少. 本例的目的就是为了实现这个效果.预览图: 1.自定义Button. /** * 长按连续响应的Button * Created by admin on 15-6-1. */ public class LongClickButton extends

随机推荐