当前位置: 移动技术网 > IT编程>移动开发>Android > Android自定义view实现圆形waveview

Android自定义view实现圆形waveview

2019年07月29日  | 移动技术网IT编程  | 我要评论

最近学习了贝塞尔曲线的一些知识,刚好项目中需要实现一个圆形进度,然后就将实现的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。

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网