文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

AndroidFlutter实现GIF动画效果的方法详解

2024-04-02 19:55

关注

前言

我们之前介绍了不少有关动画的篇章。前面介绍的动画都是只有一个动画效果,那如果我们想对某个组件实现一组动效,比如下面的效果,该怎么办?

staggered animation

这个时候我们需要用到组合动效, Flutter 提供了交错动画(Staggered Animation)的方式实现。对于多个 Anmation 对象,可以共用一个 AnimationController,然后在不同的时间段执行动画效果。这就有点像 GIF 图片一样,一帧帧图像播放实现连续的动画。

交错动画机制

交错动画的实现基于以下几个要点:

听起来有点抽象,我们以一张图来表述就清晰多了,假设我们有4个动画对象,分别控制组件的透明度(Opacity),宽度(Width),高度(Height)和颜色(Color),交错动画过程如下:

时序示意图

controller 是一个从0到1的归一化的动画控制,其实对应的就是动画时长的归一化。然后 Opacity 透明度动效占据了0-0.25区间;Width 占据了0.25-0.5区间;Height 占据了0.5-0.75区间;最后是 Color 占据了0.75-1.0的区间。区间对应就是动画的时间间隔,只是每个区间内的Tween 动画对象的取值范围都是0-1以控制从起始值到结束值。我们可以理解为是 AnimationController 将多个 Animation 对象按序(也可以重合)拼接起来形成复合形式的动画。

代码实现

看上面的说明是不是觉得还有些难以理解,我们来一段示例代码就很容易明白了。下面的代码我们定义了一个共用的_controller,然后四段动画对象_opaticy_width_height 和_color。其中关键的实现是使用了 Tween 对象的 animate 方法,并指定了一个 CurvedAnimation 对象作为 其parent 参数。而这个CurvedAnimation实际使用 Interval 来切分_controller 的动画时间,从而可以将多个 Animation 对象组合起来。

import 'package:flutter/material.dart';

class StaggeredAnimationDemo extends StatefulWidget {
  StaggeredAnimationDemo({Key? key}) : super(key: key);

  @override
  _StaggeredAnimationDemoState createState() => _StaggeredAnimationDemoState();
}

class _StaggeredAnimationDemoState extends State<StaggeredAnimationDemo>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _opacity;
  late Animation<double> _width;
  late Animation<double> _height;
  late Animation<Color?> _color;

  @override
  void initState() {
    _controller =
        AnimationController(duration: Duration(seconds: 2), vsync: this)
          ..addListener(() {
            setState(() {});
          });
    _opacity = Tween<double>(begin: 0.5, end: 1.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          0.0,
          0.25,
          curve: Curves.easeIn,
        ),
      ),
    );
    _width = Tween<double>(begin: 0.0, end: 2.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          0.25,
          0.5,
          curve: Curves.easeIn,
        ),
      ),
    );
    _height = Tween<double>(begin: 0.0, end: 2.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          0.5,
          0.75,
          curve: Curves.easeIn,
        ),
      ),
    );
    _color = ColorTween(begin: Colors.green, end: Colors.blue).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(
          0.75,
          1.0,
          curve: Curves.easeIn,
        ),
      ),
    );
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('交错动画'),
      ),
      body: Center(
        child: Opacity(
          opacity: _opacity.value,
          child: Container(
            width: 100 + 100 * _width.value,
            height: 100 + 100 * _height.value,
            color: _color.value,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.play_arrow),
        onPressed: () {
          if (_controller.isCompleted) {
              _controller.reverse();
            } else if (!_controller.isAnimating) {
              _controller.forward();
          }
        },
      ),
    );
  }
}

我们来看一下运行效果,可以看到运行的动画过程其实就是4段动画效果拼接来的,先是透明度改变,然后是宽度改变,再之后是高度改变,最后是颜色的改变。

运行效果

Interval 介绍

我们来看一下关键的 Interval 类的介绍。

A curve that is 0.0 until [begin], then curved (according to [curve]) from 0.0 at [begin] to 1.0 at [end], then remains 1.0 past [end].

Interval 类继承自 Curve,所不同的是,在 begin 之前曲线的值一直保持为0.0,而在 end 之后一直保持为1.0。所以可以理解为,在 AnimationController 启动动画后,Interval 曲线其实也已经在绘制,只是有效的取值区间只在 begin 到 end 之间,下面就是 Interval 的一种示例曲线图。

image.png

从 Interval 的源码也能看出来,其中 clamp 方法限制了取值范围,当 t <= begin 的时候取值就是0,当 t >= end的时候,取值就是1.0。

@override
double transformInternal(double t) {
  assert(begin >= 0.0);
  assert(begin <= 1.0);
  assert(end >= 0.0);
  assert(end <= 1.0);
  assert(end >= begin);
  t = ((t - begin) / (end - begin)).clamp(0.0, 1.0);
  if (t == 0.0 || t == 1.0)
    return t;
  return curve.transform(t);
}

总结

本篇介绍了交错动画的实现机制和示例,通过交错动画给了我们更多动效组合的空间,从而可以实现类似 GIF图片的那种多帧组合在一起的动画效果。

到此这篇关于Android Flutter实现GIF动画效果的方法详解的文章就介绍到这了,更多相关Android Flutter GIF动画效果内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯