Flutter 水波纹动画效果实现

Flutter 水波纹动画效果实现

  • 1. 先上效果图:
  • 2. 实现
    • 2.1 尺寸渐变结合透明度渐变
    • 2.2 多个基本动画效果叠加
  • 3. 总结

1. 先上效果图:

Flutter 水波纹动画效果实现_第1张图片

2. 实现

我们将该动画拆成三部分来实现就比较容易了,分别是尺寸大小渐变动画、透明度渐变动画和叠加组合动画。
尺寸变换数值由补间动画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控制;动画结束时生成新的圆形动画,同时销毁旧的圆形动画,达到循环不熄的效果。

  1. 首先初始化生成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();
      }
    });
  }
  1. 创建动画控制器,每次在动画结束时,生成新的动画
///创建蓝牙检索动画控制器
  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。

你可能感兴趣的:(移动跨平台,动画,flutter)