首页 > 其他分享 >flutter动画— —显式动画

flutter动画— —显式动画

时间:2024-03-04 22:22:22浏览次数:29  
标签:动画 const Text 显式 dispose controller child override flutter

常见的显式动画有RotationTransition、FadeTransition、ScaleTransition、SlideTransition、 AnimatedIcon。在显示动画中开发者需要创建一个AnimationController,通过AnimationController 控制动画的开始、暂停、重置、跳转、倒播等。

RotationTransition(旋转动画)、 AnimationController

示例1:AnimationController普通用法
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {   //加 with SingleTickerProviderStateMixin
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this,  //程序的刷新频率与手机的频率统一
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 5), //程序的执行时间
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          RotationTransition(
            turns: _controller, //调用
            child: const FlutterLogo(  //Logo
              size: 150,
            ),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Wrap(
              spacing: 10,
              alignment: WrapAlignment.center,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
                ElevatedButton(
                    onPressed: () {
                      _controller.stop(); //停止播放
                    },
                    child: const Text("Stop")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reset(); //重置
                    },
                    child: const Text("rest")),
                ElevatedButton(
                    onPressed: () {
                      _controller.repeat(); //重复播放
                    },
                    child: const Text("repeat"))
              ],
            ),
          )
        ],
      ),
    );
  }
}
示例2:lowerBound upperBound
AnimationController 用于控制动画,它包含动画的启动 forward() 、停止 stop() 、反向播放 reverse() 等方法。 AnimationController 会在动画的每一帧,就会生成一个新的值。默认情况 下, AnimationController 在给定的时间段内线性的生成从 0.0 到1.0(默认区间)的数字 ,我们也 可以通过 lowerbound 和 upperBound 来修改 AnimationController 生成数字的区间。
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
        vsync: this,
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
        duration: const Duration(seconds: 1),
        lowerBound: 3, //第三圈转到第五圈
        upperBound: 5);
    _controller.addListener(() {
      print(_controller.value);
    });
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          RotationTransition(
            turns: _controller,
            child: const FlutterLogo(
              size: 100,
            ),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Wrap(
              spacing: 10,
              alignment: WrapAlignment.center,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
                ElevatedButton(
                    onPressed: () {
                      _controller.stop(); //停止播放
                    },
                    child: const Text("Stop")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reset(); //重置
                    },
                    child: const Text("rest")),
                ElevatedButton(
                    onPressed: () {
                      _controller.repeat(); //重复播放
                    },
                    child: const Text("repeat"))
              ],
            ),
          )
        ],
      ),
    );
  }
}

FadeTransition(透明到显示)

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this,
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
        lowerBound: 0.5, //第三圈转到第五圈
        upperBound: 1
    );
  }

  @override
  void dispose() {
// TODO: implement dispose
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          FadeTransition(
            opacity: _controller,
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}

ScaleTransition(动画放大与缩小)、Tween

示例1:AnimationController控制动画:
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          ScaleTransition(
            scale: _controller,
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}
示例2: AnimationController结合Tween控制动画:
默认情况下, AnimationController 对象值的范围是[0.0,1.0]。如果我们需要构建UI的动画值在不同 的范围或不同的数据类型,则可以使用 Tween 来添加映射以生成不同的范围或数据类型的值
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          ScaleTransition(
            scale: _controller.drive(Tween(begin: 1, end: 2)), //动画开始与结束的大小
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}

SlideTransition(位移)

这是一负责平移的显示动画组件,使用时需要通过position属性传入一个Animated表示位移程度,通常 借助Tween实现。
示例1: _controller.drive驱动动画
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this,
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SlideTransition(
            position: _controller.drive(Tween(
                begin: const Offset(0, 0),
                end: const Offset(1.2, 0) //表示实际的位置向右移动自身宽度的1.2倍
                )),
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}
示例2:Tween.animate 驱动动画
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SlideTransition(
            position: Tween(
                    begin: const Offset(0, 0),
                    end: const Offset(1.2, 0) //表示实际的位置向右移动自身宽度的1.2倍
                    )
                .animate(_controller),
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}
示例3: 链式操作修改动画效果
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 1),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SlideTransition(
            position: Tween(
                    begin: const Offset(0, -1),
                    end: const Offset(0, 0.8) //表示实际的位置向右移动自身宽度的1.2倍
                    )
                .chain(CurveTween(curve: Curves.bounceIn)) //运动的曲线即运动的效果
                .animate(_controller),
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}
示例4: 链式操作修改动动画执行时间(交错式动画)
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    _controller = AnimationController(
      vsync: this, //Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 3),
    );
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          SlideTransition(
            position: Tween(
                    begin: const Offset(0, -1),
                    end: const Offset(0, 0.6) //表示实际的位置向右移动自身宽度的1.2倍
                    )
                .chain(CurveTween(curve: Curves.bounceIn))
                .chain(CurveTween(curve: const Interval(0.6, 0.8)))//最后的百分之20的时间完成动画

                .animate(_controller),
            child: const FlutterLogo(size: 80),
          ),
          const SizedBox(
            height: 40,
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(10, 0, 0, 0),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.spaceEvenly,
              children: [
                ElevatedButton(
                    onPressed: () {
                      _controller.forward(); //正序播放一次
                    },
                    child: const Text("Forward")),
                ElevatedButton(
                    onPressed: () {
                      _controller.reverse(); //倒序播放一次
                    },
                    child: const Text("Reverse")),
              ],
            ),
          )
        ],
      ),
    );
  }
}

AnimatedIcon

AnimatedIcon顾名思义,是一个用于提供动画图标的组件,它的名字虽然是以Animated开头,但是他 是一个显式动画组件,需要通过progress属性传入动画控制器,另外需要由Icon属性传入动画图标数据
class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key});
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  @override
  void initState() {
// TODO: implement initState
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: const Duration(seconds: 1)); //过度的时间为一秒
  }

  @override
  void dispose() {
// TODO: implement dispose
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () {
          _controller.forward();
        },
      ),
      appBar: AppBar(
        title: const Text('Title'),
      ),
      body: Center(
        child: AnimatedIcon(
            icon: AnimatedIcons.menu_close, progress: _controller, size: 40), //这是menu到close的过度
      ),
    );
  }
}

 

 

标签:动画,const,Text,显式,dispose,controller,child,override,flutter
From: https://www.cnblogs.com/xbinbin/p/18048109

相关文章

  • Flutter组件
    两个常用的组件:Material和Scaffold修饰App和H5一样很固定。1.Container2.Text3.pictureimport'package:flutter/material.dart';voidmain(){runApp(MaterialApp(home:Scaffold(appBar:AppBar(title:Text("Flutter")),bod......
  • Flutter widget_id: key 的使用
    Flutterwidgetid(唯一标识):keykey的作用Key是一个附加到元素(widgets,semantics,renderobjects等)的标识符。它用于控制框架是否应将旧widget与当前树中的其他widget匹配起来。简单来说,Keys的作用主要在于保持状态和在widget树重建时识别哪些widget是相同的。key的......
  • Flutter 定义局部路由 Navigator
    Flutter中,通常我们使用Navigator来管理全局的页面路由,在整个应用中维护一个路由堆栈。但是,有些情况下你可能需要一个局部路由,也就是在应用的某个部分内部维护一个独立的路由堆栈,而不影响全局路由。为了实现这一点,你可以在你的应用中创建一个新的Navigator局部路由简单使用......
  • Isolate线程通信 flutter
    A、B互传消息A、B都创建自己的接收端口和发送端口A将自己的发送端口发送给对面B,B才能拿到A的发送端口,给A发送消息A监听自己的接收端口,拿到B发给自己的消息B监听自己的接收端口,拿到A发给自己的消息voidfunction_main()async{print("当前线程:"+Isolate.current.debu......
  • Vue CLI 系列之(十五)过渡与动画
    过渡与动画Vue封装的过渡与动画1.前置知识CSS3动画【2D转换、3D转换、过渡、动画】参考网站:https://www.runoob.com/css3/css3-animations.html<h1v-show="isShow"id="title">显示了</h1><style> h1{ /*通过animation把"donghua"动画捆绑到h1元素,时长:1......
  • Flutter 页面跳转并返回数据
     主页面FutureonSubmit()async{finalresult=awaitGet.to(constPageGoodsSelectList());print(result.name);goodsId.value=result.id;setState((){goodsname.value=result.name;});}调用onSubmit跳转到下一个页面 onChildT......
  • 为什么iOS包比Android包大 flutter
    由于Android系统已经内置了Skia,所以Flutter在打包APK(Android应用安装包)时,不需要再将Skia打入APK中,但iOS系统并未内置Skia,所以构建iPA时,也必须将Skia一起打包 安卓1.在debug模式下,so库打入了x86_64、x86、arm64-v8a,总共22.28M2.在release模式下,so库只有armeabi-v7a,总共3.4......
  • 假期vue学习笔记11 动画
    <template>  <divid="root">    <Test/>    <Test2/>    <Test3/>  </div></template><script>importTestfrom'./components/Test.vue'importTest2from'./comp......
  • Flutter界面跳转
    第一种带参数跳转import'package:flutt/scrond_page.dart';import'package:flutt/third_page.dart';import'package:flutter/cupertino.dart';import'package:flutter/material.dart';voidmain(){runApp(constCupertinoApp(......
  • Flutter 使用inspector 调试UI
    1.在AndroidStudio中点击Flutterinspector2.点击FlutterPerformace-openDevtool在浏览器中调试3.点选中widget可以在widget树中和模拟器中相互点击调试、相应控件会高亮4.其他功能 ......