Android水波纹载入控件CircleWaterWaveView使用详解
作者:一语成空 发布时间:2021-10-27 23:06:58
标签:Android,水波纹
一、效果图
本控件已上传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


猜你喜欢
- 场景:使用Fragment实现切页。类结构:一:ActivityActivity中使用getSupportFragmentManager()
- 在 C语言中,占位符是一种用于格式化输出的特殊字符,通常用于 printf() 等输出函数中,用于指定输出的格式和内容。在本文中,我们将详细
- 程序中的错误分为编译时的错误和运行时的错误。编译时的错误主要是语法错误,比如:句尾没有加分号,括号不匹配,关键字错误等,这类错误比较容易修改
- 前言有时,我们可能需要从 PDF 文档中提取表格数据,例如,当PDF发票的表格中存储了一些有用的信息,需要提取数据以进行进一步分析时。在这篇
- 说到关注功能,可能很多小伙伴要说了。谁不会写但是没有合理的架构,大家写出来的代码很可能是一大堆的复制粘贴。比如十几个页面,都有这个关注按钮。
- 在前一期中,我们做了悬浮头部的两个tab切换和下拉刷新效果,后来项目中要求改成三个tab,当时就能估量了一下,如果从之前的改,也不是不可以,
- 一、前言前面我们介绍了运算符的一部分运算符,现在我们把剩余的他介绍完全来二、运算符赋值运算符所谓赋值,就是一个等于号连接的两个如int a=
- 一.递归方法1.递归就是自己调用本身的方法,前提是有方法。2.递归使用找出递归的规律递归要有出口条件,也就是结束条件3.注意事项递归次数不能
- maven打包指定jdk的版本问题今天遇到个问题,项目中新写了一个接口,其中用到了lambda表达式,本地跑是没问题的,但提交到gitLab
- 1. F1弹出帮助文档先找个后缀是pdf、docx等格式的的帮助文档,将它放在项目的helpDoc下。设置其“复制到输出
- 一,描写叙述 在多线程下编程的时候。大家可能会遇到一种需求,就是我想在我开启的线程都结束时,同一时候获取
- 目录什么是Insets?Insets相关类InsetsStateInsetsStateControllerInsetsSourceInset
- 从英文中重建数字给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)。按 升序 返回原始的数字。示例 1:输入:s
- 前言在项目中为了灵活配置,我们常采用配置文件,常见的配置文件就比如xml和properties,springboot允许使用properti
- 前言:发送邮件,肯定是每个公司都会有的基本业务。很多公司都会选择把发送邮件作为一个基础服务,对外提供接口。直接调用就可发邮件了。但是我们都知
- 本文所述为C#事务处理(Execute Transaction)的一个实例,包含了创建SqlTransaction 对象并用SqlConne
- 项目需求为APP的使用单位有很多部门,各个部分的业务也是独立的,所以开发的APP中如果把所有的模块都显示出来然后再做权限分配,会显得屏幕全是
- Settings -> Editor -> General -> Use soft wraps in editor&nbs
- 前言:这里所说的全局Dialog是指无论当前应用是处于哪一个页面上,都能够及时弹出Dialog来提示用户一些信息,用户体验不会很好,一般应用
- 一、背景假如:黑客黑进了数据库,或者离职人员导出了数据,那么就可能导致这些敏感数据的泄漏。因此我们就需要找到一种方法来解决这个问题。二、解决