欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android自定义view实现圆形waveview

程序员文章站 2022-03-23 13:38:43
最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的waveview记录一下。需要使用的知识大概有自定义view、贝塞尔曲线、valueanima...

最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的waveview记录一下。需要使用的知识大概有自定义view、贝塞尔曲线、valueanimator(属性动画)、xfermode等。

以下为效果图:

Android自定义view实现圆形waveview

废话不多说,直接上代码这里只是一些重要的代码。如果需要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、绘制贝塞尔曲线。以下为原理图。

Android自定义view实现圆形waveview

/**
* 初始化贝塞尔曲线上的点
*/
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。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。