我们将该动画拆成三部分来实现就比较容易了,分别是尺寸大小渐变动画、透明度渐变动画和叠加组合动画。
尺寸变换数值由补间动画Tween填补,辅以线性变换;这里圆形的大小变化我设置的是50~290范围,当然你可以设置其他范围:
var animation = Tween(begin: 50.0, end: 290.0)
.animate(CurvedAnimation(parent: controller, curve: Curves.linear));
使用 AnimationController 控制动画:
var controller = AnimationController(
duration: const Duration(milliseconds: 4000), vsync: this);
2.1 尺寸渐变结合透明度渐变
尺寸大小变化和透明度值变化遵循上面创建的同一个补间动画,圆形效果使用ClipOval控件进行裁剪:
AnimatedBuilder(
animation: controller,
builder: (BuildContext context, Widget? child) {
return Opacity(//透明度变化
opacity: 1.0 - ((animation.value - 50.0) / 240.0),
child: ClipOval(
child: Container(
width: animation.value,
height: animation.value,
color: const Color(0xff9fbaff),
),
),
);
}
);
到这里已经完成了基本的单个圆形变化效果,下面实现多个叠加效果。
2.2 多个基本动画效果叠加水波纹是一个新旧动画不断交替的效果,始终显示5个圆,5个圆顺序间隔开来,间隔时间相同;每个圆形动画由一个controller控制;动画结束时生成新的圆形动画,同时销毁旧的圆形动画,达到循环不熄的效果。
首先初始化生成5个初始圆:使用计时器一次间隔1秒 ///初始化蓝牙检索动画,依次添加5个缩放动画,形成水波纹动画效果
void _startAnimation() {
//动画启动前确保_children控件总数为0
_children.clear();
int count = 0;
//添加第一个圆形缩放动画
_addSearchAnimation(true);
//以后每隔1秒,再次添加一个缩放动画,总共添加4个
_searchBluetoothTimer =
Timer.periodic(const Duration(milliseconds: 1000), (timer) {
if (!mounted) return;
_addSearchAnimation(true);
count++;
if (count >= 4) {
timer.cancel();
}
});
}
创建动画控制器,每次在动画结束时,生成新的动画
///创建蓝牙检索动画控制器
AnimationController _createController() {
var controller = AnimationController(
duration: const Duration(milliseconds: 4000), vsync: this);
controller.addStatusListener((status) {
Log.e("tag", status);
if (status == AnimationStatus.completed) {
controller.dispose();
if (_controllers.contains(controller)) {
_controllers.remove(controller);
}
//每次动画控件结束时,添加新的控件,保持动画的持续性
if (!_disposeSearchBluetoothAnimation) _addSearchAnimation(false);
}
});
return controller;
}
3. 总结
到这里已经完成了整个实现步骤,完整代码链接https://github.com/crazylii/WaterRipples。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)