<强>一、效果图强>
本控件已上传Github,欢迎星和叉,项目地址:CircleWaterWaveView
<强>二、设计思路强>
观察效果图,可以看的出,该自定义控件由三个部分构成:外圆,内圆,正弦曲线。他们的关系如下图:
因为控件是动态的,所以我们需要一个线程去不停地绘制,所以我选择了SurfaceView来作为该控件地父类,该控件地核心是如何去绘制波浪,我采用如下的思路来进行内圆下部地绘制。利用内圆与正弦曲线地交集,来绘制只
核心代码如下:
/* * *绘制图像 * * @author鲁迅 */私人空间drawCanvas(帆布画布){ 如果(帆布==null) 返回;//画背景圆圈 画布。setDrawFilter(新PaintFlagsDrawFilter(0,油漆。ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG)); canvas.drawCircle (mCenterPoint。x, mCenterPoint。y, mOutRadius mOutCirclePaint); canvas.drawCircle (mCenterPoint。x, mCenterPoint。y, mRadius mCirclePaint); 如果(mStart) {//计算正弦曲线的路径 int mH=mCenterPoint。y + mRadius - mCurrentHight; int长度=2 * mOutRadius; 路径路径=new路径(); 路径。函数(0,mH); for (int i=0;我& lt;长度;我+ +){ int x=我; int y=(int) (sin(数学。toRadians (x + mTranX)/振幅)* mRadius/增加); 路径。画线(x, mH + y); } 路径。画线(长度、mH); 路径。画线(长度,mCenterPoint。y + mRadius); 路径。画线(0,mCenterPoint。y + mRadius); 路径。画线(0,mH); canvas.save();//保存画布状态//这里与圆形取交集,除去正弦曲线多画的部分 路径pc=new路径(); pc.addCircle (mCenterPoint。x, mCenterPoint。y, mRadius Path.Direction.CCW); 画布。clipPath (pc, Region.Op.INTERSECT);//切割画布 画布。drawPath(路径,mWaterPaint);//绘制文字 画布。mCenterPoint drawText (flowNum +“%”。x, mCenterPoint。y + mTextSise/2, mTextPaint); canvas.restore();//恢复画布状态 } }
<强>三、性能优化强>
绘制线程如下:
/* * *绘制界面的线程 * * @author鲁迅 */私人类RenderThread实现Runnable { @Override 公共空间run () {//不停绘制界面,这里是异步绘制,不采用外部通知开启绘制的方式,水波根据数据更新才会开始增长 而(isDrawing) { 如果(mWaterTaget比;mCurrentHight) { mCurrentHight=mCurrentHight + mUpSpeed; 如果(mWaterTaget & lt;=mCurrentHight) { mCurrentHight=mWaterTaget; } } 如果(mStart) { 如果(mTranX比;mRadius) { mTranX=0; } mTranX -=mWaterSpeed; } drawUI (); SystemClock.sleep(25);//控制刷新速率,减少cpu占用 } } }
通过为SurfaceHolder添加监听,来控制绘制线程。当控件被隐藏不在前台显示时,自动结束绘制线程,当控件显示在前台时,再次开启绘制。
@Override 公共空间surfaceCreated (SurfaceHolder SurfaceHolder) { isDrawing=true; 新线程(renderThread) .start (); } @Override 公共空间surfaceChanged (SurfaceHolder SurfaceHolder, int格式,int宽度,int高度){ int最小长度=数学。分钟(宽度、高度); mOutRadius=最小长度/2; mRadius=(int)(0.5 *(最小长度- mOutStrokeWidth)); mCenterPoint=new点(最小长度/2,最小长度/2); 如果(进步!=0){ setProgress(进步); } } @Override 公共空间surfaceDestroyed (SurfaceHolder SurfaceHolder) { isDrawing=false; } >之前<强>四,属性化强>
部分设置属性,除了通过代码设置外,同时也加入了在XML文件中,直接以属性赋值的操作。
应用程序:输入textColor=" # 00 ff00” 应用:水彩=" # 00 ff00” 应用:strokeColor=" # 00 ff00” 应用:backgroudColor=" # 00 ff00” 应用:振幅=" 1.0 "(水波振幅) 应用:max=" 1000 " 应用:进步=" 500 " 应用:增加=" 6.0 "(水波涨幅) 应用:upSpeed=?”(上涨速度) 应用:waterSpeed=?”[移动速度) 应用:strokeSize=" 4 dp” 应用:textSize=" 20 dp”Android水波纹载入控件CircleWaterWaveView使用详解