flutter动画

Implicit Animations

隐式动画:通常以Animated为开头的(AnimatedIcon,AnimatedBuilder是显式动画)数据变化时会自动进行动画,不用循环播放、不用随时中断、不用多个动画协同,它实现的是一种状态到另一种状态的改变

Explicit Animations

显示动画:以Transition结尾的,需要自己控制动画过程

以RotationTransition为例

默认_controller 是从0.0——1.0,可以通过 lowerbound 和 upperBound 来修改 AnimationController 生成数字的区间。也可以构建UI时候利用Tween来修改范围,如代码中注释部分_controller.drive(Tween(begin: 1, end: 2)),

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

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {  
 //单个动画加with SingleTickerProviderStateMixin,多个动画加with TickerProviderStateMixin
  late AnimationController _controller;
  @override
  void initState() {
        super.initState();
        _controller = AnimationController(
      vsync: this,  //程序的刷新频率与手机的频率统一
//Vsync 机制可以理解为是显卡与显示器的通信桥梁,显卡在渲染每一帧之前会等待垂
// 直同步信号,只有显示器完成了一次刷新时,发出垂直同步信号,显卡才会渲染下一帧,确保刷新率和帧率保
// 持同步,以达到供需平衡的效果,防止卡顿现象。
      duration: const Duration(seconds: 5), //程序的执行时间
      lowerBound: 3, 
      upperBound: 5
    );
        _controller.addListener((){
        print("_controller值为${_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, //调用
            //turns: _controller.drive(Tween(begin: 1, end: 2))
            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(reverse:true); //重复播放  正序播放倒叙播放循环
                    },
                    child: const Text("repeat"))
              ],
            ),
          )
        ],
      ),
    );
  }
}
 链式操作修改动画效果  
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)))
                        //在_controller 到60%时开始,80%时结束

                .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")),
              ],
            ),
          )
        ],
      ),
    );
  }
}

自定义动画AnimatedBuilder

运用场景 当组件有比较复杂的动画,比如缩放平移变淡等多个动画作用与一个widget时

child: AnimatedBuilder(
    animation:_controller,
    builder:(Buildcontext context,Widget child){
    //第二个参数child作用是重新构建时,child不变,提升性能
        return 0pacity(
            opacity:Tween(begin:0.0,end:0.5).animated(_controller).value,
                    //上面是之前的链式调用写法
            child: Container(
                width: Tween(begin:200.0,end:300.0).evaluate(_controller),//一种写法
                height:200 +100 *controller.value,//另一种写法
                color: Colors.blue,
                child: child,
            ),//Container
        );// 0pacity
    },
    child: Center( //这里的child会插入到builder里面的child,作为不会变化的widget
        child: Text(
        "Hi”
        style:TextStyle(fontSize:72)
        ),// Text
    ),// Center
),//AnimatedBuilder

当_animationController变化是,build函数会自动重新构建,相当于运行了setstate,源码实际上也是运行了setstate

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值