欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > Android Canvas动画实践:实现小球旋转、扩散、聚合效果

Android Canvas动画实践:实现小球旋转、扩散、聚合效果

2025/4/18 11:19:30 来源:https://blog.csdn.net/liuhaikang/article/details/147008889  浏览:    关键词:Android Canvas动画实践:实现小球旋转、扩散、聚合效果

引言

在Android开发中,Canvas为我们提供了一个强大的绘图工具。本文通过分析一个自定义View组件SplashView,展示如何利用Canvas实现‌小球旋转‌、‌扩散聚合‌和‌水波纹‌动画效果,并搭配关键代码片段解释实现细节。

一、效果演示

以下是动画的连贯流程:

旋转阶段‌:多个彩色小球围绕中心旋转。
扩散聚合‌:小球向外扩散后聚拢。
水波纹‌:中心出现逐渐扩大的透明圆洞,背景颜色变化。

二、小球旋转动画

旋转动画通过不断改变小球的绘制角度实现。以下是核心代码:

private class RotateState extends SplashState {private RotateState() {mValueAnimator = ValueAnimator.ofFloat(0, (float) (Math.PI * 2));mValueAnimator.setRepeatCount(2);mValueAnimator.setDuration(mRotateDuration);mValueAnimator.setInterpolator(new LinearInterpolator());mValueAnimator.addUpdateListener(animation -> {mCurrentRotateAngle = (float) animation.getAnimatedValue();invalidate();});mValueAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {super.onAnimationEnd(animation);mState = new MergeState();}});mValueAnimator.start();}@Overridevoid drawState(Canvas canvas) {//绘制背景drawBackground(canvas);//绘制6个小球drawCircles(canvas);}}


关键点‌:

通过三角函数(Math.cos和Math.sin)计算每个小球的位置。


三、扩散聚合动画

扩散聚合效果通过动态改变旋转半径实现,使用ValueAnimator驱动动画:

// 扩散聚合状态(MergeState类)
private class MergeState extends SplashState {private ValueAnimator mExpandAnimator;public MergeState() {// 创建扩散动画(半径从小变大)mExpandAnimator = ValueAnimator.ofFloat(mCircleRadius, mRotateRadius);mExpandAnimator.setDuration(mRotateDuration);mExpandAnimator.addUpdateListener(animation -> {mCurrentRotateRadius = (float) animation.getAnimatedValue();invalidate();});// 动画结束后反向播放(聚合效果)mExpandAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mExpandAnimator.reverse();}});mExpandAnimator.start();}@Overridepublic void drawState(Canvas canvas) {drawBackground(canvas);drawCircles(canvas, mCurrentRotateAngle, mCurrentRotateRadius);}
}


关键点‌:

ValueAnimator驱动半径从初始值到目标值的变化。
通过reverse()实现反向动画,形成“扩散-聚合”循环。


四、水波纹动画

水波纹效果通过绘制逐渐扩大的“空洞”实现,结合背景颜色变化:

// 水波纹状态(ExpandState类)
private class ExpandState extends SplashState {private ValueAnimator mHoleAnimator;public ExpandState() {mHoleAnimator = ValueAnimator.ofFloat(0, mDistance);mHoleAnimator.setDuration(mRotateDuration);mHoleAnimator.addUpdateListener(animation -> {mCurrentHoleRadius = (float) animation.getAnimatedValue();invalidate();});mHoleAnimator.start();}@Overridepublic void drawState(Canvas canvas) {drawBackground(canvas);}
}
// 绘制背景(带空洞)private void drawBackground(Canvas canvas) {if (mCurrentHoleRadius > 0) {float strokeWidth = mDistance - mCurrentHoleRadius;float radius = strokeWidth / 2 + mCurrentHoleRadius;mHolePaint.setStrokeWidth(strokeWidth);canvas.drawCircle(mCenterX, mCenterY, radius, mHolePaint);} else {canvas.drawColor(mBackgroundColor);}}


四、动画状态切换

通过状态模式管理不同动画阶段:

// 抽象状态类
private abstract class SplashState {public abstract void drawState(Canvas canvas);
}// 动画结束后的状态切换逻辑
mExpandAnimator.addListener(new AnimatorListenerAdapter() {@Overridepublic void onAnimationEnd(Animator animation) {mSplashState = new ExpandState(); // 切换到水波纹状态}
});


五、总结

通过Canvas和属性动画的配合,我们实现了三种连贯的动画效果:

小球旋转‌:基于角度动态计算位置。
扩散聚合‌:通过ValueAnimator驱动半径变化。
水波纹‌:逐渐扩大圆圈,露出原本底色。

完整代码已托管至Gitcode:GitCode - 全球开发者的开源社区,开源代码托管平台
希望本文能为你实现复杂Canvas动画提供启发!

通过代码片段与文字的结合,读者可以更直观地理解每个动画的实现方式。如果需要进一步解释某个代码细节,可以随时补充!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词