Code前端首页关于Code前端联系我们

Flutter开发:实现水波纹扩散效果的Widget

terry 2年前 (2023-09-23) 阅读数 64 #移动小程序
Flutter 开发:实现一个水波纹扩散效果的 Widget

我们在日常APP使用中肯定会遇到这种效果,那么这个效果是如何实现的呢?

确认要求

首先还是老套路。先确定需求,整理思路,然后写代码:

  1. 首先要有一个圆
  2. 这个圆会扩大然后消失
  3. 当这个圆扩大到一定程度后,再画一个圆
  4. 有限循环/无限循环
  5. 可以有/没有孩子

心中有一个想法,让我们开始实施它。

首先必须有一个圆

首先必须有一个圆。这个圆应该怎么画呢?我想到了两个选择:

  1. CustomPaint
  2. ClipOver

这两种方法都很简单,所以我选择了第二种,因为它更容易(23333)。

我不会发布代码,但我已经将其提交到github.com/wanglu1209/…

这个圆圈扩大并消失

它扩大并消失。

还记得我在上一篇文章中谈到的小箭头演示吗? --- 颤动 |我通过一个小样例给大家介绍一下动画Animation

是的,这个评分这里也是用来计算大小和透明度的。

代码如下:

Container(
  width: _radiusTween.evaluate(animation),
  height: _radiusTween.evaluate(animation),
  child: ClipOval(
    child: Opacity(
      opacity: _opacityTween.evaluate(animation),
      child: Container(
        color: color,
      ),
    ),
  ),
)
复制代码

这样我们只需要设置begin和Tween的结尾即可实现扩展和消失。

当这个圆扩大到一定程度后,再画一个圆

首先,我们都知道如何在Flutter中将一个widget放在另一个widget之上。对了,用Stack

然后我们需要创建一个List来保存我们刚刚定义的“扩大和消失的圆”。

而且我们也知道,这个“扩大消失的圆圈”需要Animationa,也就是说每个圆圈都需要Animationa❙和,那么我们还需要创建 List来控制每个“扩大和消失的圆圈”。

AnimationStatus == 完成时,移除圆圈并丢弃控制器。

并且在废弃Widget时,所有未删除的驱动程序也应该被删除。

大致代码如下:

int i = 0;
while (widget.cycles == null ? true : i < widget.cycles) {
  if (mounted) {
    setState(() {
      AnimationController _animationController;
      Animation<double> _animation;

      _animationController =
        AnimationController(vsync: this, duration: widget.duration);
      _animation = CurvedAnimation(
        parent: _animationController, curve: Curves.linear);

      _animationController.addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          children.removeAt(0);
          controllers.removeAt(0);
          _animationController.dispose();
        }
      });
      controllers.add(_animationController);
      _animationController.forward();

      widget.child != null
        ? children.insert(
        children.length - 1,
        AnimatedSpread(
          animation: _animation,
          radius: widget.radius,
          maxRadius: widget.maxRadius,
          color: widget.spreadColor,
        ))
        : children.add(AnimatedSpread(
          animation: _animation,
          radius: widget.radius,
          maxRadius: widget.maxRadius,
          color: widget.spreadColor,
        ));
    });
  }
  if (widget.cycles != null) i++;
  await Future.delayed(
    Duration(milliseconds: widget.duration.inMilliseconds ~/ 3));
}
复制代码

每个动画都有一个时长,那么我们可以根据时长设置第二个圆圈何时出现。我在这里写的是持续时间。 1/3。

看起来效果不错。

有限循环/无限循环

现在代码中就是这部分逻辑:

while (widget.cycles == null ? true : i < widget.cycles) {
  // ...
}
复制代码

这里主要是控制显示次数。毕竟,有些请求并不总是会产生连锁反应。

可以有/没有子

我这里写的默认子形状是圆形的,大小由SizedBox控制到大小♷到大小❀♷如果是还有孩子 如何保证孩子永远醒着?

插入圆的时候,只要使用List.insert(index, element)的方法就可以了。

水波纹扩散效果小部件现已捆绑。

总结

这里我用了和上一篇文章一样的逻辑,我用了AnimatedWidget

然后包裹起来❝‽‽‼‽ Future .delay编辑 . 控制下一个圆圈出现的时间。

作者:颤笔记

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门