首页 > 行业资讯 > Android 心率动画自定义控件实现

Android 心率动画自定义控件实现

时间:2023-02-10 来源: 浏览:

Android 心率动画自定义控件实现

原创 陈文管 文呓
文呓

wild_eagle_

个人博文,此公众号作为 https://www.chenwenguan.com/ 博客内容的同步,只有自由行游记单独发在公众号。

收录于合集

Android心率曲线平移动画自定义控件实现详解,并附上GitHub完整实现仓库资源。

项目上需要实现一个心率曲线波动的自定义动画,网上找了很多开源控件,没有想要的效果,综合网上已有的实现,改造实现了一个比较简单的心率波动动画,以下是实现的动画效果GIF,实际运行会平滑很多。

一、实现原理详解

1. 心率曲线的绘制

如果是绘制折线,只需要把数据点使用Path对象lineTo方法把所有数据点连接绘制即可,绘制曲线则使用cubicTo方法绘制贝塞尔曲线,让曲线连接点更平滑。每次绘制前重置Path对象,所有数据点连接完毕之后即可刷新绘制。

private void generateNewPath(float offset) { mPath.reset(); for (int i = 0; i < mSourceData.size(); i++) { // x,y表示当前点 x4,y4表示下一个点 x2,x3都是属于中间的点 x = mMarginLeft + mHearRateItemMargin * i - offset; y = getHearRateValueToViewHeight(mSourceData.get(i)); if (i == mSourceData.size() - 1) { x4 = x; y4 = y; } else { x4 = mMarginLeft + mHearRateItemMargin * (i + 1) - offset; y4 = getHearRateValueToViewHeight(mSourceData.get(i + 1)); } x2 = x3 = (x + x4) / 2; y2 = y; y3 = y4; if (i == 0) { mPath.moveTo(x, y); mPath.lineTo(x, y); } if (i != mSourceData.size() - 1) { mPath.cubicTo(x2, y2, x3, y3, x4, y4); } } }

2. 平移动画实现

在曲线还没超过绘制控件宽度的时候,逐个绘制数据点连线,当数据点超过控件宽度的时候,才进行从右往左的X轴平移动画。这边平移的动画使用属性动画的刷新,来更新曲线每个数据点的X轴坐标来实现。

这边需要注意的是:属性函数回调参数的类型不能写成Float,而是float,否则会导致setShiftXRatio没执行。

ObjectAnimator.ofFloat( this , "shiftXRatio" , 0f , 1f ); /** * setShiftXRatio * * @param shiftRatio float */ public void setShiftXRatio ( float shiftRatio ) { invalidatePath(mHearRateItemMargin * shiftRatio); }

同时设置属性动画为无限循环,如果是配置属性动画只执行一次,每新增一个数据点再启动属性动画,会有大概一秒的延迟,导致实现的动画效果不平滑,会有明显的顿挫。

setRepeatCount ( ValueAnimator .INFINITE )

在属性动画的执行监听中,用onAnimationRepeat接口来触发下一个数据点的平移动画执行,设置属性动画为无限循环之后,监听onAnimationRepeat接口而不是onAnimationEnd接口。

private Animator.AnimatorListener mAnimListener = new Animator.AnimatorListener() { @Override public void onAnimationStart( @NonNull Animator animator) { } @Override public void onAnimationEnd( @NonNull Animator animator) { } @Override public void onAnimationCancel( @NonNull Animator animator) { } @Override public void onAnimationRepeat( @NonNull Animator animator) { startNextAnim(); } };

3. 渲染问题导致绘制异常

在MUMU虚拟机上运行动画,测试了几分钟之后绘制不出来画面,报以下异常信息:

E/EGL_emulation: tid 1442: eglSurfaceAttrib(1101): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x7f51eb168a40 , error =EGL_BAD_MATCH W/OpenGLRenderer: Path too large to be rendered into a texture W/OpenGLRenderer: Shape too  large   to  be rendered  into  a texture ( 16391 x514,  max = 16384 x16384)

在布局控件中配置software属性解决。

android:layerType= "software"

二、GitHub仓库链接地址

https://github.com/wenguan0927/HeartRateAnimView

三、其他心率动画开源资源参考

Snake View(  https://github.com/txusballesteros/snake  ) 也是心率动画,只是动画是蛇形变化。

LuckyEcgDemo  (  https://github.com/SeekerFighter/LuckyEcgDemo  ) 心电图表格自定义控件实现,正式的医院心电图效果。

扩展阅读:

美图手机音乐Widget动画实现

公众号文章不支持外链,点击【阅读原文】可直接访问,网站博客会不定时更新补充内容。

版权:如无特殊注明,文章转载自网络,侵权请联系cnmhg168#163.com删除!文件均为网友上传,仅供研究和学习使用,务必24小时内删除。
相关推荐