这篇文章主要为大家详细介绍了 Android 自定义控件制作显示进度的 Button,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由 Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 "安卓" 或 "安致"。
最近看到一些应用在下载文件的时候,并没有额外弹出进度条,而是很炫的使用启动下载任务的 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 上:{aa0aa}
来源: http://www.phperz.com/article/17/0317/292099.html