Android自定义view实现圆形waveview
程序员文章站
2022-03-23 13:38:43
最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的waveview记录一下。需要使用的知识大概有自定义view、贝塞尔曲线、valueanima...
最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的waveview记录一下。需要使用的知识大概有自定义view、贝塞尔曲线、valueanimator(属性动画)、xfermode等。
以下为效果图:
废话不多说,直接上代码这里只是一些重要的代码。如果需要demo可以去下载。
首先需要自定义view的属性:
<declare-styleable name="custom_wave_view_attr"> <attr name="circle_color" format="color"></attr> //圆的颜色 <attr name="circle_background_color" format="color"></attr> //圆的背景色 <attr name="progress_wave_color" format="color"></attr> //水波纹的颜色 <attr name="progress_text_size" format="dimension"></attr> //字体的大小 <attr name="progress_text_color" format="color"></attr> //字体的颜色 </declare-styleable>
第二步自定义customwaveview
1、实现构造方法,在构造方法中获取属性值
typedarray ta = context.obtainstyledattributes(attrs,r.styleable.custom_wave_view_attr); //圆的颜色 circle_color = ta.getcolor(r.styleable.custom_wave_view_attr_circle_color,getresources().getcolor(android.r.color.black)); //圆的背景色 circle_bg_color = ta.getcolor(r.styleable.custom_wave_view_attr_circle_background_color,getresources().getcolor(android.r.color.white)); //水波纹颜色 wave_color = ta.getcolor(r.styleable.custom_wave_view_attr_progress_wave_color,getresources().getcolor(android.r.color.holo_blue_dark)); //字体的颜色 text_color = ta.getcolor(r.styleable.custom_wave_view_attr_progress_text_color,getresources().getcolor(android.r.color.black)); //字体的大小 textsize = ta.getdimension(r.styleable.custom_wave_view_attr_progress_text_size,30f); //释放资源 ta.recycle();
2、初始化画笔
//初始化背景圆画笔 mbgcirclepaint = new paint(); //抗锯齿 mbgcirclepaint.setantialias(true); //设置背景圆的背景色 mbgcirclepaint.setcolor(circle_bg_color); //设置充满 mbgcirclepaint.setstyle(paint.style.fill); //初始化水波纹画笔 mwavepaint = new paint(); //抗锯齿 mwavepaint.setantialias(true); //设置水波纹的背景色 mwavepaint.setcolor(wave_color); //设置充满 mwavepaint.setstyle(paint.style.fill); //使用xfermode获取重叠部分 mwavepaint.setxfermode(new porterduffxfermode(porterduff.mode.src_in));
3、绘制贝塞尔曲线。以下为原理图。
/** * 初始化贝塞尔曲线上的点 */ private void reset() { startp = new pointf(-width, height); nextp = new pointf(-width/2, height); threep = new pointf(0, height); fourp = new pointf(width/2, height); endp = new pointf(width, height); controllerp1 = new pointf(-width/4, height); controllerp2 = new pointf(-width * 3/4, height); controllerp3 = new pointf(width/4, height); controllerp4 = new pointf(width * 3/4, height); }
4、在ondraw方法中画贝塞尔曲线和圆
@override protected void ondraw(canvas canvas) { super.ondraw(canvas); //在透明画布上画背景圆 mcanvas.drawcircle(width/2, height/2, radius, mbgcirclepaint); //贝塞尔曲线 mpath.reset(); mpath.moveto(startp.x, startp.y); mpath.quadto(controllerp1.x, controllerp1.y, nextp.x, nextp.y); mpath.quadto(controllerp2.x, controllerp2.y, threep.x, threep.y); mpath.quadto(controllerp3.x, controllerp3.y, fourp.x, fourp.y); mpath.quadto(controllerp4.x, controllerp4.y, endp.x, endp.y); mpath.lineto(endp.x, height); mpath.lineto(-width, height); //在透明画布上绘制水波纹 mcanvas.drawpath(mpath,mwavepaint); //将画好的圆绘制在画布上 canvas.drawbitmap(mbitmap, 0, 0, null); }
5、使用动画让贝塞尔曲线动起来
/** * 开始动画 让startp的x点坐标在2s时间内循环移动到0点。 * depth---进度 * waveripple----水波纹的振幅 */ private void startanimator() { animator = valueanimator.offloat(startp.x, 0); animator.setinterpolator(new linearinterpolator()); animator.setduration(2000); //重复循环 animator.setrepeatcount(valueanimator.infinite); animator.addupdatelistener(new valueanimator.animatorupdatelistener() { @override public void onanimationupdate(valueanimator animation) { startp.x = (float) animation.getanimatedvalue(); startp = new pointf(startp.x, height - depth); nextp = new pointf(startp.x + width/2, height - depth); threep = new pointf(nextp.x + width/2, height - depth); fourp = new pointf(threep.x + width/2, height - depth); endp = new pointf(fourp.x + width/2, height - depth); controllerp1 = new pointf(startp.x + width/4, height - depth + waveripple); controllerp2 = new pointf(nextp.x + width/4, height - depth - waveripple); controllerp3 = new pointf(threep.x + width/4, height - depth + waveripple); controllerp4 = new pointf(fourp.x + width/4, height - depth - waveripple); invalidate(); } }); animator.start(); }
第三步在xml中使用自定义view
<com.criclewaveview_master.customwaveview android:id="@+id/custom_circle_wave_view" android:layout_width="wrap_content" android:layout_height="wrap_content" wave:circle_color = "@color/circle_color" android:layout_centerinparent="true" wave:circle_background_color = "@color/circle_bg_color" wave:progress_wave_color = "@color/coloraccent" wave:progress_text_size = "20sp" wave:progress_text_color = "@color/circle_color"/>
这样就完成了自定义waveview。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: 使用Docker运行SQL Server