Android水波纹载入控件CircleWaterWaveView使用详解
作者:一语成空 时间:2021-10-27 23:06:58
一、效果图
本控件已上传Github,欢迎Star和Fork,项目地址:CircleWaterWaveView
二、设计思路
观察效果图,可以看出,该自定义控件由三个部分构成:外圆、内圆、正弦曲线。他们的关系如下图:
因为控件是动态的,所以我们需要一个线程去不停地绘制,所以我选择了SurfaceView来作为该控件地父类。该控件地核心是如何去绘制波浪,我采用如下的思路来进行内圆下部地绘制。利用内圆与正弦曲线地交集,来绘制。
核心代码如下:
/**
* 绘制图像
*
* @author luxun
*/
private void drawCanvas(Canvas canvas) {
if (canvas == null)
return;
//画背景圆圈
canvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mOutRadius, mOutCirclePaint);
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mCirclePaint);
if (mStart) {
//计算正弦曲线的路径
int mH = mCenterPoint.y + mRadius - mCurrentHight;
int length = 2 * mOutRadius;
Path path = new Path();
path.moveTo(0, mH);
for (int i = 0; i < length; i++) {
int x = i;
int y = (int) (Math.sin(Math.toRadians(x + mTranX) / amplitude) * mRadius / increase);
path.lineTo(x, mH + y);
}
path.lineTo(length, mH);
path.lineTo(length, mCenterPoint.y + mRadius);
path.lineTo(0, mCenterPoint.y + mRadius);
path.lineTo(0, mH);
canvas.save();//保存画布状态
//这里与圆形取交集,除去正弦曲线多画的部分
Path pc = new Path();
pc.addCircle(mCenterPoint.x, mCenterPoint.y, mRadius, Path.Direction.CCW);
canvas.clipPath(pc, Region.Op.INTERSECT);//切割画布
canvas.drawPath(path, mWaterPaint);
//绘制文字
canvas.drawText(flowNum + "%", mCenterPoint.x, mCenterPoint.y + mTextSise / 2, mTextPaint);
canvas.restore();//恢复画布状态
}
}
三、性能优化
绘制线程如下:
/**
* 绘制界面的线程
*
* @author luxun
*/
private class RenderThread implements Runnable {
@Override
public void run() {
// 不停绘制界面,这里是异步绘制,不采用外部通知开启绘制的方式,水波根据数据更新才会开始增长
while (isDrawing) {
if (mWaterTaget > mCurrentHight) {
mCurrentHight = mCurrentHight + mUpSpeed;
if (mWaterTaget <= mCurrentHight) {
mCurrentHight = mWaterTaget;
}
}
if (mStart) {
if (mTranX > mRadius) {
mTranX = 0;
}
mTranX -= mWaterSpeed;
}
drawUI();
SystemClock.sleep(25);//控制刷新速率,减少cpu占用
}
}
}
通过为SurfaceHolder添加监听,来控制绘制线程。当控件被隐藏不在前台显示时,自动结束绘制线程,当控件显示在前台时,再次开启绘制。
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
isDrawing = true;
new Thread(renderThread).start();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
int minLength = Math.min(width, height);
mOutRadius = minLength / 2;
mRadius = (int) (0.5 * (minLength - mOutStrokeWidth));
mCenterPoint = new Point(minLength / 2, minLength / 2);
if (progress != 0) {
setProgress(progress);
}
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
isDrawing = false;
}
四、属性化
部分设置属性,除了通过代码设置外,同时也加入了在XML文件中,直接以属性赋值的操作。
app:textColor="#00ff00"
app:waterColor="#00ff00"
app:strokeColor="#00ff00"
app:backgroudColor="#00ff00"
app:amplitude="1.0"[水波振幅]
app:max="1000"
app:progress="500"
app:increase="6.0"[水波涨幅]
app:upSpeed="3"[上涨速度]
app:waterSpeed="8"[移动速度]
app:strokeSize="4dp"
app:textSize="20dp"
五、后记
代码已经上传Github,欢迎有兴趣的朋友去看看。
来源:https://blog.csdn.net/lx578111527/article/details/52797947
标签:Android,水波纹
0
投稿
猜你喜欢
Android中 视频屏幕左半部分上下滑动改变亮度右半部分上下滑动改变声音
2021-08-13 02:57:12
Android开发之设置开机自动启动的几种方法
2021-12-04 20:35:37
C#加密解密类实例程序
2022-01-25 18:17:09
C#特性(Attribute)
2022-08-18 18:34:51
使用Postman传递arraylist数据给springboot方式
2022-08-27 01:13:01
SpringBoot中发送QQ邮件功能的实现代码
2022-09-25 10:19:59
浅谈SpringBoot中的Bean初始化方法 @PostConstruct
2022-06-11 07:21:17
Java全面细致讲解Cookie与Session及kaptcha验证码的使用
2021-09-03 23:10:56
Android 实现图片生成卷角和圆角缩略图的方法
2021-08-12 16:14:12
java利用Future实现多线程执行与结果聚合实例代码
2023-09-24 11:07:18
解析C#中@符号的几种使用方法详解
2022-11-09 03:26:03
c#分页读取GB文本文件实例
2021-09-13 10:18:39
关于synchronized有趣的同步问题
2021-11-03 05:46:55
Spring Boot 配置和使用多线程池的实现
2022-09-04 19:53:02
Android四种常见布局方式示例教程
2022-05-25 09:35:03
Java毕业设计实战项目之在线服装销售商城系统的实现流程
2023-03-27 00:15:31
基于获取JAVA路径,包括CLASSPATH外的路径的方法详解
2022-12-20 21:30:03
C#利用正则判断输入是否为纯数字、容器类
2022-10-10 03:00:39
Java反射机制详解
2023-10-01 12:18:04
Android 设置应用全屏的两种解决方法
2023-05-07 01:27:50