Flutter:动画

这篇具有很好参考价值的文章主要介绍了Flutter:动画。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

学习参考:老孟 flutter动画
基本上开发时使用的组件都有其动画,关于动画方面的知识,一般情况很少会用到。因此这里只学习关于动画的基本知识。

AnimationController

Flutter中的AnimationController是一个用于控制动画的类。它可以控制动画的开始、停止、反转、重置等操作,并且可以设置动画的持续时间、曲线等属性。

AnimationController 通常在 initState 方法中初始化,在dispose中释放动画

使用AnimationController需要先创建一个实例,然后设置动画的持续时间、曲线等属性,最后通过调用forward()方法来启动动画。在动画运行过程中,可以通过调用reverse()方法来反转动画,通过调用stop()方法来停止动画,通过调用reset()方法来重置动画。

AnimationController还可以添加监听器,用于监听动画的状态变化。例如,可以通过添加addListener()方法来监听动画的值变化,从而更新UI界面。通过添加addStatusListener来监听动画的状态

// 单个 AnimationController 的时候使用 SingleTickerProviderStateMixin,多个 AnimationController 使用 TickerProviderStateMixin。
class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  double size = 100;
  // 定义动画控制器对象
  late AnimationController _controller;

  // AnimationController 通常在 initState 方法中初始化
  
  void initState() {
    // TODO: implement initState
    super.initState();
    // vsync 用于防止屏幕外动画消耗不必要的资源
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    // 监听动画帧的变化,在每一帧中调用setState来更新UI,AnimationController 的值默认是 0 到 1
    _controller.addListener(() {
      setState(() {
        // 使size从100到200
        size = 100 + 100 * _controller.value;
      });
    });
    
    //  监听动画的状态,当动画正序完成后反向执行动画
    _controller.addStatusListener((status) {
      // 动画状态status的值有:dismissed(动画停止在开始处)、forward(正向运行)、reverse(反向运行)、completed(动画停止在结束处)
      if (status == AnimationStatus.completed) {
        _controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controller.forward();
      }
    });
  }

  
  void dispose() {
    super.dispose();
    //释放动画
    _controller.dispose();
  }

  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
      onTap: () {
        // 启动动画
        _controller.forward();
      },
      child: Container(
        width: size,
        height: size,
        color: Colors.blue,
        alignment: Alignment.center, // 设置文字居中
        child: const Text("点击变大"),
      ),
    ));
  }
}

Flutter:动画

Tween

Flutter中的Tween是用于在动画中定义起始值和结束值之间的插值计算的类。它可以将一个范围内的值映射到另一个范围内的值,从而实现动画效果

上面的案例可以修改为

class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  double size = 100;
  // 定义动画控制器对象
  late AnimationController _controller;
  // 定义一个动画对象
  late Animation _animation;

  // AnimationController 通常在 initState 方法中初始化
  
  void initState() {
    // TODO: implement initState
    super.initState();
    // vsync 用于防止屏幕外动画消耗不必要的资源
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    final Tween tween = Tween(begin: 100.0, end: 200.0);
    _animation = tween.animate(_controller);
    _animation.addListener(() {
      setState(() {
        size = _animation.value;
      });
    });
  }

  
  void dispose() {
    super.dispose();
    //释放动画
    _controller.dispose();
  }

  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
      onTap: () {
        // 启动动画
        _controller.forward();
      },
      child: Container(
        width: size,
        height: size,
        color: Colors.blue,
        alignment: Alignment.center, // 设置文字居中
        child: const Text("点击变大"),
      ),
    ));
  }
}

同理也可以改变颜色

class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  Color _color = Colors.blue;
  // 定义动画控制器对象
  late AnimationController _controller;
  // 定义一个动画对象
  late Animation _animation;

  // AnimationController 通常在 initState 方法中初始化
  
  void initState() {
    // TODO: implement initState
    super.initState();
    // vsync 用于防止屏幕外动画消耗不必要的资源
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(seconds: 2),
    );

    final Tween tween = ColorTween(begin: Colors.blue, end: Colors.red);
    _animation = tween.animate(_controller);
    _animation.addListener(() {
      setState(() {
        _color = _animation.value;
      });
    });
  }

  
  void dispose() {
    super.dispose();
    //释放动画
    _controller.dispose();
  }

  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
      onTap: () {
        // 启动动画
        _controller.forward();
      },
      child: Container(
        width: 100,
        height: 100,
        color: _color,
        alignment: Alignment.center, // 设置文字居中
        child: const Text("点击改变颜色"),
      ),
    ));
  }
}

Flutter:动画

Curve

动画中还有一个重要的概念就是 Curve,即动画执行曲线。使动画的效果能够以匀速、加速、减速、抛物线等各种速率变化。

// 使用了 chain 方法将 ColorTween 和 CurveTween 组合起来
  final Animatable<Color?> tween =
      ColorTween(begin: Colors.blue, end: Colors.red)
          .chain(CurveTween(curve: Curves.easeInOut));
  _animation = tween.animate(_controller);
  _animation.addListener(() {
    setState(() {
      _color = _animation.value;
    });
  });

动画组件

Flutter 系统提供了20多个动画组件,这些组件都是基于动画的核心知识实现的。动画组件分为两大类:

  • 隐式动画组件:只需提供给组件动画开始、结束值,组件创建 AnimationController、Curve、Tween,执行动画,释放AnimationController
  • 显式动画组件:需要设置 AnimationController,控制动画的执行,使用显式动画可以完成任何隐式动画的效果,甚至功能更丰富一些,不过你需要管理该动画的 AnimationController 生命周期
  • 显示动画组件和隐式动画组件中各有一个万能的组件,它们是 AnimatedBuilder 和 TweenAnimationBuilder,当系统中不存在我们想要的动画组件时,可以使用这两个组件

隐式动画组件的使用

class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  double _opacity = 1.0;
  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
            onTap: () {
              setState(() {
                _opacity = 0;
              });
            },
            child: AnimatedOpacity(
              opacity: _opacity,
              duration: const Duration(seconds: 1),
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
                alignment: Alignment.center, // 设置文字居中
                child: const Text("点击改变颜色"),
              ),
            )));
  }
}

Flutter:动画
**TweenAnimationBuilder **
TweenAnimationBuilder 是 Flutter 中的一个动画构建器,可以用于创建一个在两个值之间进行动画的动画组件。使用 TweenAnimationBuilder 需要指定两个值之间的插值器(Tween),以及动画的持续时间和动画结束后的回调函数。

class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  // 一开始不能定义null,否则运行会报错
  late ColorTween _tween = ColorTween(begin: Colors.blue, end: Colors.blue);
  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
            onTap: () {
              setState(() {
                _tween = ColorTween(begin: Colors.blue, end: Colors.red);
              });
            },
            child: TweenAnimationBuilder(
              duration: const Duration(seconds: 1),
              tween: _tween,
              builder: (BuildContext context, Color? value, Widget? child) {
                return Container(
                  width: 100,
                  height: 100,
                  color: value,
                  alignment: Alignment.center, // 设置文字居中
                  child: const Text("点击改变颜色"),
                );
              },
            )));
  }
}
class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  //  动画控制器
  late AnimationController _controller;
  // 颜色动画
  late Animation _colorAnimation;
  // 大小动画
  late Animation _sizeAnimation;

  
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 2));
    // 使用AnimationController的drive方法将一个Tween对象与AnimationController关联起来
    _colorAnimation =
        _controller.drive(ColorTween(begin: Colors.blue, end: Colors.red));
    // 使用AnimationController的drive方法将一个Tween对象与AnimationController关联起来
    _sizeAnimation = _controller
        .drive(SizeTween(begin: const Size(100, 50), end: const Size(50, 100)));
    super.initState();
  }

  
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Center(
        //创建一个手势识别器
        child: GestureDetector(
            onTap: () {
              setState(() {
                // 开始动画
                _controller.forward();
              });
            },
            child: AnimatedBuilder(
                animation: _controller,
                builder: (context, widget) {
                  return Container(
                    width: _sizeAnimation.value.width,
                    height: _sizeAnimation.value.height,
                    color: _colorAnimation.value,
                    alignment: Alignment.center, // 设置文字居中
                    child: const Text("点击改变颜色"),
                  );
                })));
  }
}

Flutter:动画

列表动画

AnimatedList提供了一种简单的方式使列表数据发生变化时加入过渡动画

AnimatedList主要属性如下表。

属性 说明
itemBuilder 一个函数,列表的每一个索引会调用,这个函数有一个animation参数,可以设置成任何一个动画
initialItemCount item的个数
scrollDirection 滚动方向,默认垂直
controller scroll控制器

列表数据的插入和删除有进出场动画需要调用AnimatedListState指定的方法,只删除原数据并调用setState方法是没有动画效果的

class _YcHomeBodyState extends State<YcHomeBody>
    with SingleTickerProviderStateMixin {
  // 定义一个全局的key来管理AnimatedListState对象,并将其传递给AnimatedList构造函数
  final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();
  // 定义列表
  final List<String> _itemList = ["item 1", "item 2", "item 3"];

  // 新增
  void addItem() {
    _itemList.add('item ${_itemList.length + 1}');
    _listKey.currentState?.insertItem(_itemList.length - 1);
  }

  // 删除
  void removeItem() {
    // 删除操作要注意,要先删除列表中的数据在删除AnimatedListState的状态
    // 并且关于index下标的操作,要放在删除操作之前,不然会导致删除时下标错误报错
    int index = _itemList.length - 1;
    String title = _itemList[index];
    _itemList.removeAt(index);
    _listKey.currentState?.removeItem(
      index,
      (context, animation) => SlideTransition(
        position: animation.drive(CurveTween(curve: Curves.easeIn)).drive(
            Tween<Offset>(begin: const Offset(1, 1), end: const Offset(0, 1))),
        child: Card(
          child: ListTile(
            title: Text(title),
          ),
        ),
      ),
    );
  }

  
  Widget build(BuildContext context) {
    return Column(
      children: [
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            ElevatedButton(onPressed: addItem, child: const Text('增加')),
            ElevatedButton(onPressed: removeItem, child: const Text('减少')),
          ],
        ),
        // AnimatedList需要有高度
        Expanded(
            child: AnimatedList(
                key: _listKey,
                initialItemCount: _itemList.length, // item的个数
                itemBuilder: (context, index, animation) {
                  // 为每一个item设置动画,将曲线动画和平移动画结合在一起
                  return SlideTransition(
                    // 动画对象,用于控制子组件的平移动画
                    position: animation
                        .drive(CurveTween(curve: Curves.easeIn))
                        .drive(Tween<Offset>(
                            begin: const Offset(1, 1),
                            end: const Offset(0, 1))),
                    child: Card(
                      child: ListTile(
                        title: Text(_itemList[index]),
                      ),
                    ),
                  );
                }))
      ],
    );
  }
}

这个东西挺难搞的,出了不少问题。删除时一点要注意:

  • 删除操作要注意,要先删除列表中的数据在删除AnimatedListState的状态
  • 并且关于index下标的操作,要放在删除操作之前,不然会导致删除时下标错误报错

关于新增时简单,删除时复杂我查到的解释是:

在AnimatedList中,新增操作只需要添加数据到列表中并调用AnimatedListState的insertItem方法即可,AnimatedListState会自动处理动画效果。
但是删除操作需要手动处理动画效果,因为AnimatedListState无法自动处理删除动画。因此,需要手动调用AnimatedListState的removeItem方法,并在其中指定删除动画的实现方式。

Flutter:动画

Hero

Hero用于在两个页面之间实现平滑的过渡效果。它可以将一个widget从一个页面转换到另一个页面,同时保持其外观和位置不
变。
Hero动画通常用于在两个页面之间传递图像或其他媒体内容时,可以使用户感觉到这些内容在两个页面之间平滑地移动。

class _YcHomeBodyState extends State<YcHomeBody> {
  
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          Navigator.push(
            context,
            MaterialPageRoute(builder: (context) => const SecondPage()),
          );
        },
        child: Hero(
          tag: 'imageHero',
          child: Image.network(
              'https://scpic3.chinaz.net/files/default/imgs/2023-06-07/f84b7dd1b1e82805_s_w285.jpg'),
        ),
      ),
    );
  }
}

class SecondPage extends StatelessWidget {
  const SecondPage({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: GestureDetector(
        onTap: () {
          Navigator.pop(context);
        },
        child: Hero(
          tag: 'imageHero',
          child: Image.network(
              'https://scpic3.chinaz.net/files/default/imgs/2023-06-07/f84b7dd1b1e82805_s_w285.jpg'),
        ),
      ),
    );
  }
}

Flutter:动画文章来源地址https://www.toymoban.com/news/detail-481856.html

到了这里,关于Flutter:动画的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter:动画

    学习参考:老孟 flutter动画 基本上开发时使用的组件都有其动画,关于动画方面的知识,一般情况很少会用到。因此这里只学习关于动画的基本知识。 Flutter中的 AnimationController 是一个用于控制动画的类。它可以控制动画的开始、停止、反转、重置等操作,并且可以设置动画

    2024年02月08日
    浏览(36)
  • Flutter中动画的实现

           动画三要素         控制动画的三要素:Animation、Tween、和AnmaitionController         Animation: 产生的值的序列,有CurveAnimation等子 类,, 可以将值赋值给Widget的宽高或其他属性,进而控制widget发生变化         Tween:可以定义值的变化范围,  继承自 An

    2024年03月10日
    浏览(38)
  • Flutter 06 动画

    1、动画原理: 在任何系统的Ul框架中,动画实现的原理都是相同的,即:在一段时间内,快速地多次改变Ul外观;由于人眼会产生视觉暂留,所以最终看到的就是一个“连续”的动画,这和电影的原理是一样的。 我们将UI的一次改变称为一个动画帧,对应一次屏幕刷新,而决

    2024年02月05日
    浏览(62)
  • Flutter Flar动画实战

    在Flare动面出现之前,Flare动画大体可以分为使用AnimationController控制的基础动画以及使用Hero的转场动画,如果遇到一些复杂的场景,使用这些动画方案实现起来还是有难度的。不过,随着Flutter开始支持Flare矢量动面,Flutter的动画开发也变得越来越简单。事实上,Flare动画是一

    2024年02月14日
    浏览(34)
  • Flutter实现动画列表AnimateListView

    由于业务需要,在打开列表时,列表项需要一个从右边飞入的动画效果,故封装一个专门可以执行动画的列表组件,可以自定义自己的动画,内置有水平滑动,缩放等简单动画。花里胡哨的动画效果由你自己来定制吧。 功能: 1.可自定义动画。 2.内置水平滑动和缩放动画。

    2024年02月11日
    浏览(46)
  • Flutter 动画(显式动画、隐式动画、Hero动画、页面转场动画、交错动画)

    当前案例 Flutter SDK版本: 3.13.2 Tween({this.begin,this.end})  两个构造参数,分别是  开始值 和 结束值 ,根据这两个值,提供了控制动画的方法,以下是常用的; controller.forward()   :   向前,执行 begin 到 end 的动画,执行结束后,处于end状态; controller.reverse()   :   反向,当动画

    2024年02月20日
    浏览(48)
  • Flutter之自定义路由切换动画

    在Flutter中,我们可以通过Navigator来实现路由管理,包括路由的跳转和返回等。默认情况下,Flutter提供了一些简单的路由切换动画,但是有时候我们需要自定义一些特殊的动画效果来提高用户体验。本文将介绍如何在Flutter中实现自定义的路由切换动画。 在Flutter中,路由切换

    2024年02月10日
    浏览(37)
  • Flutter 平移动画 — 4种实现方式

    Flutter 旋转动画 — RotationTransition Flutter 平移动画 — 4种实现方式 Flutter 淡入淡出与逐渐出现动画 Flutter 尺寸缩放、形状、颜色、阴影变换动画 Flutter 列表Item动画 — AnimatedList实现Item左进左出、淡入淡出 Flutter Hero 实现共享元素转场动画 Flutter Hero 实现径向变换动画 — 圆形变

    2023年04月17日
    浏览(39)
  • Flutter 缩放动画组件封装与使用

    在 Flutter 中,动画是为了提升用户体验而不可或缺的一部分。在应用程序中,缩放动画是常用的一种交互效果,可以使界面元素在用户交互时具有生动感。为了更好地组织代码和提高复用性,我们可以封装一个缩放动画组件,以下是一个简单的封装示例: 在使用缩放动画组件

    2024年01月19日
    浏览(41)
  • Flutter动画库:animations(路由过渡动画或者页面切换动画)

    animations 是一个 Flutter 库,它提供了一组用于创建动画效果的工具和组件。 这个库的核心重点是路由过渡动画或者页面切换动画 地址 https://pub-web.flutter-io.cn/packages/animations 安装 看了下官方文档和官方例子,然后就有点懵。差点以为找错库了。还好flutter中的库可以直接点开(

    2024年02月16日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包