前言

之前一篇我们讲了 flutter组合动画实现的方式 —— 交错动画。借助 gif 和绘图技巧是可以做到类似 gif 那种效果的。本篇我们来一个应用实例,我们让轮子在草地滚动着前进,而且还能粘上“绿色的草”,运行效果如下动画所示。

动画解析

上面实现的效果实际上由三个动画组成:

  • 轮子前进的动画
  • 轮子滚动
  • 轮子的边缘颜色渐变(由黑色变成绿色)

这三个动画是同时进行的,因此需要使用到交错动画,即使用一个 animationcontroller来控制三个 tween 对象实现上述的动画组合。

编码实现

首先是轮子组件的定义,为了让轮子转动的效果能够看到,我们给轮子填充了线性的渐变色,然后轮子的尺寸、旋转速度(time)和边框颜色由上级组件来控制。整个实现很简单,就是一个加了装饰的 container 而已。

class wheel extends statelesswidget {
  final double size;
  final color color;
  final double time;
  const wheel({
    key? key,
    required this.size,
    required this.time,
    required this.color,
  }) : super(key: key);

  @override
  widget build(buildcontext context) {
    return container(
      width: size,
      height: size,
      transform: matrix4.identity()..rotatez(2 * pi * time),
      transformalignment: alignment.center,
      decoration: boxdecoration(
        border: border.all(color: color, width: 10.0),
        borderradius: borderradius.circular(size / 2),
        gradient: lineargradient(
          colors: [
            colors.white,
            colors.orange[100]!,
            colors.orange[400]!,
          ],
        ),
      ),
    );
  }
}

然后是整个页面布局,整个页面布局其实就是一个 stack,然后底部是绿色的 container再加两个轮子,都是使用 positioned 来确定各自的位置。然后就是通过受控的tween 对象控制轮子的旋转速度,轮子外边沿颜色和移动的距离,代码如下,其中轮子移动距离通过控制边距实现。

widget build(buildcontext context) {
  final bottomheight = mediaquery.of(context).size.height / 3;
  return scaffold(
    appbar: appbar(
      title: const text('交错动画'),
    ),
    body: stack(children: [
      positioned(
        child: container(
          width: double.infinity,
          height: bottomheight,
          color: colors.green[400],
        ),
        bottom: 0,
        left: 0,
        right: 0,
      ),
      positioned(
          child: wheel(
            size: wheelsize,
            color: _color.value!,
            time: _time.value,
          ),
          left: _offset.value * mediaquery.of(context).size.width,
          bottom: bottomheight),
      positioned(
          child: wheel(
            size: wheelsize,
            color: _color.value!,
            time: -_time.value,
          ),
          right: _offset.value * mediaquery.of(context).size.width,
          bottom: bottomheight)
    ]),
    floatingactionbutton: floatingactionbutton(
      child: icon(icons.play_arrow),
      onpressed: () {
        if (_controller.iscompleted) {
          _controller.reverse();
        } else if (!_controller.isanimating) {
          _controller.forward();
        }
      },
    ),
  );
}

最后就是构建受animationcontroller 控制的 tween 对象了,这个在flutter 做出 gif 动画效果已经介绍过了,代码如下:

late animationcontroller _controller;
late animation<double> _time;
late animation<double> _offset;
late animation<color?> _color;

final wheelsize = 80.0;

@override
void initstate() {
  _controller =
      animationcontroller(duration: duration(seconds: 4), vsync: this)
        ..addlistener(() {
          setstate(() {});
        });

  _time = tween<double>(begin: 0, end: 8.0).animate(
    curvedanimation(
      parent: _controller,
      curve: interval(
        0.0,
        1.0,
        curve: curves.linear,
      ),
    ),
  );
  _offset = tween<double>(begin: 0, end: 1.0).animate(
    curvedanimation(
      parent: _controller,
      curve: interval(
        0.0,
        1.0,
        curve: curves.easeincubic,
      ),
    ),
  );
  _color = colortween(begin: colors.black87, end: colors.green).animate(
    curvedanimation(
      parent: _controller,
      curve: interval(
        0.0,
        0.8,
        curve: curves.easein,
      ),
    ),
  );
  super.initstate();
}

就这样,一对奔向对方的轮子动画效果就完成了!

总结

交错动画实际上可以实现非常有创意的动效,只是这样会需要很高的绘图技巧,比如使用 custompaint 来做。接下来的几篇我们来介绍一下 custompaint相关的内容。

以上就是android flutter制作交错动画的示例代码的详细内容,更多关于android flutter交错动画的资料请关注其它相关文章!