自定义View之炫丽的进度条
来源:互联网 发布:gettemppath linux 编辑:程序博客网 时间:2024/04/25 16:30
Android自定义View之炫丽的进度条
好久没有写Blog了,昨天意外看到自己无意中写的一篇文章,访问量都有1k+,突然之间觉得写博客,分享知识是一件多么幸福的事情!今天我给大家分享一个自定义view来绘制一个项目中经常用的炫丽立体效果的进度条.虽然不怎么有难度,但是项目中经常用到,希望能帮助大家项目中的一些问题,帮到大家。
代码下载地址:http://download.csdn.net/detail/zgkxzx/9762403
实现原理
主要是通过Paint的setXfermode(Xfermode xfermode) 图像混合模式,关于paint的混合模式的知识,小编就不在这里科普了,自己到百度上面谷歌一下就知道了。下面我们找重点的地方讲解。如下,多种混合模式的效果图:
这里,我们用的的模式是SRC_IN,从效果图中,我们很清晰看出,当SRC是蓝色正方形图片,DST为橙色圆形图片时,SRC_IN效果,即为当SRC与DST重叠发生,交集部分为两图交集区域,并展现出SRC交集区域。这里,我们项目中SRC为
DST资源为通过画布画的扇形图像,由于图片源SRC是一张切图,我们不容易控制进度,那么我们通过控制扇形的区域,来实现整体画布的进度条的控制。如下图,没有找到比较好的作图工具,自己用Galaxy Note机手绘图形进行分析(画的不好,不要吐槽~~)。
当DST扇形(红色区域)在画布上扫过,与SRC的交集部分,即画布上面最终展现的区域(紫色区域),这里的扇形起始边是-270度。我们可以根据实际需要进行调整。好了,我们不多说了,直接上源码分析。
代码实现
自定义View的步骤一般是onMeasure,onLayout,onDraw,这里我们只需要测量和绘制就行了。
第一步:初始化参数
//背景图片和进度条图片 private Bitmap bgBmp; private Bitmap bgProcess; private PorterDuffXfermode mMode; private Paint mXferPaint; private RectF mOval; private Paint mTextPaint; //百分比 private int mPercent; //边长 private int sideLength; //缩放比例 private float scale = 1.0f; private void init() { bgBmp = BitmapFactory.decodeResource(getResources(), R.mipmap.ring_bg); if (processImg != null) { bgProcess = ((BitmapDrawable) processImg).getBitmap(); } else bgProcess = BitmapFactory.decodeResource(getResources(), R.mipmap.ring_bg_1); mMode = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN); mXferPaint = new Paint(); mXferPaint.setColor(Color.GREEN); mXferPaint.setXfermode(mMode); mXferPaint.setAntiAlias(true); mOval = new RectF(); mOval.left = 0; mOval.top = 0; mPercent = 0; mTextPaint = new Paint(); mTextPaint.setColor(textColor); mTextPaint.setTextSize(textSize); mTextPaint.setAntiAlias(true); Typeface font = Typeface.createFromAsset(context.getAssets(), textFont != null ? textFont : DEFAULR_FONT); mTextPaint.setTypeface(font); }
在初始化中,主要是对需要绘画的几个画笔进行了初始化。这里比较重要的是我们用的的PorterDuffXfermode混合图像模式,在这里采用了SRC_IN模式。画笔画出的扇形和原始进度条图片发生交集后,显示原始进度条图片的部分。在设计进度条之前,小编考虑到可扩展性,本来是准备采用DST_IN模式,这样进度条显示部分为交集的扇形部分,这样进度条的颜色通过xml倒是很方便配置,但是进度条通过drawArc方法画出来的是屏幕效果图,效果没有切片能展现立体的效果。
第二步:onMeasure方法实现测量
int widthMode = MeasureSpec.getMode(widthMeasureSpec); int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int width; int height; int bgWidth = bgBmp.getWidth(); int bgHight = bgBmp.getHeight(); if (widthMode == MeasureSpec.EXACTLY) { width = widthSize; } else { width = bgWidth; } if (heightMode == MeasureSpec.EXACTLY) { height = heightSize; } else { height = bgHight; } //得到边长,这里默认进度条为正方形的控件 sideLength = Math.min(width, height); //计算比例缩放系数 scale = (float) sideLength / bgWidth; setMeasuredDimension(sideLength, sideLength);
在测量部分,如果采用包裹方式,控件的大小为原切片背景大大小;如果EXACTLY方式,那么原切片货更加精确的长宽进行比例缩放。
第三步:关键部分onDraw方法的实现
//矩阵运算 主要是根据xml的设置对原切片进行比例缩放 Matrix matrix = new Matrix(); matrix.postScale(scale, scale); mXferPaint.setXfermode(null); canvas.drawBitmap(bgBmp, matrix, mXferPaint); //将绘制操作保存到新的图层(离屏缓存) int saveCount = canvas.saveLayer(0, 0, sideLength, sideLength, null, Canvas.MATRIX_SAVE_FLAG | Canvas.CLIP_SAVE_FLAG | Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.CLIP_TO_LAYER_SAVE_FLAG); mOval.left = 0; mOval.top = 0; mOval.right = sideLength; mOval.bottom = sideLength; mXferPaint.setXfermode(null); //绘制扇形区域,关于-235,290这个角度,根据实际切片的角度填写,找美工妹子要就行了~~~ canvas.drawArc(mOval, -235, 290 * mPercent / MAX_PROCESS, true, mXferPaint); mXferPaint.setXfermode(mMode); canvas.drawBitmap(bgProcess, matrix, mXferPaint); //绘制进度字 String text = mPercent + ""; canvas.drawText(text, 0, text.length(), sideLength / 2 - ViewUtil.getTextWidth(mTextPaint, text) / 2, sideLength / 2 + ViewUtil.getTextHeight(mTextPaint, text) / 2, mTextPaint); canvas.restoreToCount(saveCount);
至此,代码部分也说完了,此自定义view并不怎么复杂,但是工程中经常用到,希望能帮到大家,一起学习进步…
本来是准备代码在Github和csdn各上传一份便于大家参考,可惜最近Github连接不上去了。
代码下载地址:http://download.csdn.net/detail/zgkxzx/9762403
- 自定义View之炫丽的进度条
- 自定义view之圆形进度条
- 自定义View之-ProgressBar进度条
- 自定义View之圆环进度条
- 自定义view之圆形进度条
- 自定义view之圆形进度条
- 自定义View的圆圈进度条
- 自定义View之简单自定义圆形进度条
- Android自定义View之三种流行进度条的写法
- Android自定义View之如期相遇的百分比进度条RatioProgress
- 自定义View之Android波浪效果的进度条
- Android自定义View之实现环形进度条
- 自定义View之绘制交替进度条
- 自定义view学习系列之圆形进度条
- Android自定义View之圆形进度条
- 自定义View之饼状进度条
- android自定义view之半圆形进度条
- 自定义view之圆形进度条初体验
- php中curl_exec中的CURLOPT_RETURNTRANSFER
- 第一周安装环境或软件真不是一件轻松的事
- CentOS中安装JDK与Intellij idea
- js--DOM
- 信息、信息熵、条件熵、信息增益、信息增益比、基尼系数、相对熵、交叉熵
- 自定义View之炫丽的进度条
- iOS H5页面OC与JS简单交互
- logstash配置
- Java中的动态代理机制
- CSS样式
- C和C++中读取不定数量的输入数据
- CocoaPods安装和使用教程
- 原型模式
- Shell学习