Flutter_学习记录_动画的简单了解

AnimationController简单实现如下的效果图:

1. 只用AnimationController实现简单动画

1.1 完整代码案例

dart 复制代码
import 'package:flutter/material.dart';

class AnimationDemo extends StatefulWidget {
  const AnimationDemo({super.key});

  @override
  State<AnimationDemo> createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> with TickerProviderStateMixin {

  late AnimationController animationDemoController;
  @override
  void initState() {
    super.initState();

    animationDemoController = AnimationController(
      vsync: this,
      // 初始值,要在 lowerBound 和 upperBound 之间
      value: 32.0,
      // 最小值
      lowerBound: 32.0,
      // 最大值
      upperBound: 100.0,
      // 设置动画的时间
      duration: Duration(milliseconds: 3000)
    );

    animationDemoController.addListener((){
      // 更新页面
      setState(() {
        
      });
    });

    // 添加status的监听
    animationDemoController.addStatusListener((AnimationStatus status){
      print(status);
    });
  }

  @override
  void dispose() {
    super.dispose();
    // 销毁 animationDemoController
    animationDemoController.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimationDemo"),
      ),
      body: Center(
        child: IconButton(
          icon: Icon(Icons.favorite),
          iconSize: animationDemoController.value,
          onPressed: (){
            switch (animationDemoController.status) {
              case AnimationStatus.completed:
                // 反转动画
                animationDemoController.reverse();
                break;
              default:
                // 开始动画
                animationDemoController.forward();
            }
          },
        ),
      ),
    );
  }
}

1.2 代码说明

(1) AnimationController

  • animationDemoController 是动画的核心控制器。
  • duration 定义了动画的持续时间(例如 2 秒)。
  • vsync 参数确保动画与屏幕刷新同步,避免资源浪费。
  • value 设置初始值。
  • lowerBound 设置最小值。
  • upperBound 设置 最大值。

(2) addListener 添加监听,可以监听到 animationDemoController.value的值的变化。

  • 如果需要需要用到 animationDemoController.value的值更新UI,则需要调用 setState的方法。
dart 复制代码
animationDemoController.addListener((){
      // 更新页面
      setState(() {
        
      });
    });

(3)addStatusListener 添加动画状态的监听,只有添加了这个监听,才能在后面获取到动画状态的变化。

dart 复制代码
            switch (animationDemoController.status) {
              case AnimationStatus.completed:
                // 反转动画
                animationDemoController.reverse();
                break;
              default:
                // 开始动画
                animationDemoController.forward();
            }

(4) 开始动画

dart 复制代码
animationDemoController.forward()

(5)反转动画

dart 复制代码
animationDemoController.reverse();

2. 用AnimationControllerAnimation实现简单动画

2.1 完整代码示例

dart 复制代码
import 'package:flutter/material.dart';

class AnimationDemo extends StatefulWidget {
  const AnimationDemo({super.key});

  @override
  State<AnimationDemo> createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> with TickerProviderStateMixin {

  late AnimationController animationDemoController;
  late Animation animation;
  late Animation animationColor;
  // 设置动画取消
  late CurvedAnimation curve;

  @override
  void initState() {
    super.initState();

    animationDemoController = AnimationController(
      vsync: this,
      // 设置动画的时间
      duration: Duration(milliseconds: 3000)
    );

    animation = Tween(begin: 32.0, end: 100.0).animate(animationDemoController);
    animationColor = ColorTween(begin: Colors.red, end: Colors.green).animate(animationDemoController);

    animationDemoController.addListener((){
      // 更新页面
      setState(() {
        
      });
    });

    // 添加status的监听
    animationDemoController.addStatusListener((AnimationStatus status){
      print(status);
    });
  }

  @override
  void dispose() {
    super.dispose();
    // 销毁 animationDemoController
    animationDemoController.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimationDemo"),
      ),
      body: Center(
        child: IconButton(
          icon: Icon(Icons.favorite),
          iconSize: animation.value,
          color: animationColor.value,
          onPressed: (){
            switch (animationDemoController.status) {
              case AnimationStatus.completed:
                // 反转动画
                animationDemoController.reverse();
                break;
              default:
                // 开始动画
                animationDemoController.forward();
            }
          },
        ),
      ),
    );
  }
}

2.2 代码说明

(1) Tween

  • Tween(begin: xx, end:xx) 定义了动画的范围:
  • begin 是起始值。
  • end 是结束值。

(2) animationDemoController.value animation.value 来替代

3. 用AnimationControllerAnimationCurvedAnimation实现简单动画

CurvedAnimation 可以添加缓动效果(如 Curves.easeInOut),完整代码示例:

dart 复制代码
import 'package:flutter/material.dart';

class AnimationDemo extends StatefulWidget {
  const AnimationDemo({super.key});

  @override
  State<AnimationDemo> createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> with TickerProviderStateMixin {

  late AnimationController animationDemoController;
  late Animation animation;
  late Animation animationColor;
  // 设置动画曲线
  late CurvedAnimation curve;

  @override
  void initState() {
    super.initState();

    animationDemoController = AnimationController(
      vsync: this,
      // 设置动画的时间
      duration: Duration(milliseconds: 3000)
    );

    curve = CurvedAnimation(parent: animationDemoController, curve: Curves.bounceOut);
    animation = Tween(begin: 32.0, end: 100.0).animate(curve);
    animationColor = ColorTween(begin: Colors.green, end: Colors.red).animate(curve);

    animationDemoController.addListener((){
      // 更新页面
      setState(() {
        
      });
    });

    // 添加status的监听
    animationDemoController.addStatusListener((AnimationStatus status){
      print(status);
    });
  }

  @override
  void dispose() {
    super.dispose();
    // 销毁 animationDemoController
    animationDemoController.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimationDemo"),
      ),
      body: Center(
        child: IconButton(
          icon: Icon(Icons.favorite),
          iconSize: animation.value,
          color: animationColor.value,
          onPressed: (){
            switch (animationDemoController.status) {
              case AnimationStatus.completed:
                // 反转动画
                animationDemoController.reverse();
                break;
              default:
                // 开始动画
                animationDemoController.forward();
            }
          },
        ),
      ),
    );
  }
}

4 用AnimationControllerAnimatedWidget实现简单动画

完整代码实例:

dart 复制代码
import 'package:flutter/material.dart';

class AnimationDemo extends StatefulWidget {
  const AnimationDemo({super.key});

  @override
  State<AnimationDemo> createState() => _AnimationDemoState();
}

class _AnimationDemoState extends State<AnimationDemo> with TickerProviderStateMixin {

  late AnimationController animationDemoController;
  late Animation animation;
  late Animation animationColor;
  // 设置动画曲线
  late CurvedAnimation curve;

  @override
  void initState() {
    super.initState();

    animationDemoController = AnimationController(
      vsync: this,
      // 设置动画的时间
      duration: Duration(milliseconds: 3000)
    );

    curve = CurvedAnimation(parent: animationDemoController, curve: Curves.bounceOut);
    animation = Tween(begin: 32.0, end: 100.0).animate(curve);
    animationColor = ColorTween(begin: Colors.green, end: Colors.red).animate(curve);

    // 添加status的监听
    animationDemoController.addStatusListener((AnimationStatus status){
      print(status);
    });
  }

  @override
  void dispose() {
    super.dispose();
    // 销毁 animationDemoController
    animationDemoController.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("AnimationDemo"),
      ),
      body: Center(
      	//  AnimationHeart 是基于 AnimatedWidget 创建的
        child: AnimationHeart(
          animations: [animation, animationColor], 
          controller: animationDemoController
        ),
      ),
    );
  }
}

// 基于 AnimatedWidget 创建 AnimationHeart的控件
class AnimationHeart extends AnimatedWidget {

  final List animations;
  final AnimationController controller;

  const AnimationHeart({
    super.key, 
    required this.animations, 
    required this.controller
  }) : super(listenable: controller);

  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(Icons.favorite),
      iconSize: animations[0].value,
      color: animations[1].value,
      onPressed: (){
        switch (controller.status) {
          case AnimationStatus.completed:
            // 反转动画
            controller.reverse();
            break;
          default:
            // 开始动画
            controller.forward();
        }
      },
    );
  }
}
相关推荐
EQ-雪梨蛋花汤11 分钟前
【Flutter】Unity 三端封装方案:Android / iOS / Web
android·flutter·unity
sunly_4 小时前
Flutter:组件9、图片预览
flutter
APItesterCris5 小时前
Flutter 移动端开发:集成淘宝 API 实现商品数据实时展示 APP
大数据·数据库·flutter
明似水12 小时前
Flutter 弹窗队列管理:支持优先级的线程安全通用弹窗队列系统
javascript·安全·flutter
坚果的博客18 小时前
坚果派已适配的鸿蒙版flutter库【持续更新】
flutter·华为·开源·harmonyos
ak啊1 天前
Flutter项目架构设计方案
flutter
JarvanMo1 天前
在Dart泛型中应该优先使用dynamic还是Object?
前端·flutter·dart
恋猫de小郭1 天前
Flutter 在 Dart 3.8 开始支持 Null-Aware Elements 语法,自动识别集合里的空元素
android·前端·flutter
恋猫de小郭1 天前
Flutter Widget IDE 预览新进展,开始推进落地发布
android·前端·flutter
Ya-Jun1 天前
常用第三方库:flutter_boost混合开发
android·flutter·ios