自定义控件 - 可以显示进度的Button

来源:互联网 发布:淘宝设置全场满包邮 编辑:程序博客网 时间:2024/06/07 06:56

        最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的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



原创粉丝点击