flutter SlideTransition实现平移动画

志在巅峰的攀登者,不会陶醉在沿途的某个脚印之中,在码农的世界里,优美的应用体验,来源于程序员对细节的处理以及自我要求的境界,年轻人也是忙忙碌碌的码农中一员,每天、每周,都会留下一些脚印,就是这些创作的内容,有一种执着,就是不知为什么,如果你迷茫,不妨来瞅瞅码农的轨迹。

如果你有兴趣 你可以关注一下公众号 biglead 来获取最新的学习资料。


flutter 动画状态监听器

AnimationController

    //动画控制器
     AnimationController controller;
    //AnimationController是一个特殊的Animation对象,在屏幕刷新的每一帧,就会生成一个新的值,
    // 默认情况下,AnimationController在给定的时间段内会线性的生成从0.0到1.0的数字
    //用来控制动画的开始与结束以及设置动画的监听
    //vsync参数,存在vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源
    //duration 动画的时长,这里设置的 seconds: 2 为2秒,当然也可以设置毫秒 milliseconds:2000.
    controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    //动画开始、结束、向前移动或向后移动时会调用StatusListener
    controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        //动画从 controller.reverse() 反向执行 结束时会回调此方法
        print("status is completed");
        // controller.reset(); 将动画重置到开始前的状态
        //开始执行
        //controller.forward();
      } else if (status == AnimationStatus.dismissed) {
        //动画从 controller.forward() 正向执行 结束时会回调此方法
        print("status is dismissed");
        //controller.forward();
      }else if (status == AnimationStatus.forward) {
        print("status is forward");
        //执行 controller.forward() 会回调此状态
      }else if (status == AnimationStatus.reverse) {
        //执行 controller.reverse() 会回调此状态
        print("status is reverse");
      }
    });

AnimationController 的常用操作说明

说明
controller.forward()正向开始执行动画
controller.reverse()反向开始执行动画
controller.reset()重置动画到初始状态
controller.dispose()取消/停止动画

flutter AnimationStatus 动画状态说明

说明
AnimationStatus.forward执行 controller.forward() 会回调此状态
AnimationStatus.reverse执行 controller.reverse() 会回调此状态
AnimationStatus.dismissed动画从 controller.reverse() 反向执行 结束时会回调此方法
AnimationStatus.completed)动画从 controller.forward() 正向执行 结束时会回调此方法

1 水平向右平移

在这里插入图片描述

移动前
在这里插入图片描述
移动后
在这里插入图片描述

源码

  //动画控制器
  AnimationController controller;
  Animation<Offset> animation;
//初始化 
    //用来控制动画的开始与结束以及设置动画的监听
    //vsync参数,存在vsync时会防止屏幕外动画(动画的UI不在当前屏幕时)消耗不必要的资源
    //duration 动画的时长,这里设置的 seconds: 2 为2秒,当然也可以设置毫秒 milliseconds:2000.
    controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    //动画开始、结束、向前移动或向后移动时会调用StatusListener
    controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        //AnimationStatus.completed 动画在结束时停止的状态
        //ontroller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        //AnimationStatus.dismissed 表示动画在开始时就停止的状态
        //controller.forward();
      }
    });
    //begin: Offset.zero, end: Offset(1, 0) 以左下角为参考点,相对于左下角坐标 x轴方向向右 平移执行动画的view 的1倍 宽度,y轴方向不动,也就是水平向右平移
    //begin: Offset.zero, end: Offset(1, 1) 以左下角为参考点,相对于左下角坐标 x轴方向向右 平移执行动画的view 的1倍 宽度,y轴方向 向下 平衡执行动画view 的1倍的高度,也就是向右下角平移了
    animation =
        Tween(begin: Offset.zero, end: Offset(1, 0)).animate(controller);

//开始执行动画 
controller.forward();

执行动画的view



  //平移
  Widget buildSlideTransition() {
    return Center(
    //SlideTransition 用于执行平移动画
      child: SlideTransition(
        position: animation,
        //将要执行动画的子view
        child: Container(
          width: 200,
          height: 200,
          color: Colors.grey,
        ),
      ),
    );
  }

在这里插入图片描述

    //begin: Offset(1, 0), end: Offset(1, 1) 在构建布局页面的时候,执行动画的view 会先相对于自身左下角水平向右移动 执行动画的view 的1倍 宽度,
    //动画开始后 再次 移动到 end: Offset(1, 1)
    animation =
        Tween(begin: Offset(1, 0), end: Offset(1, 1)).animate(controller);

2 向右下角平移
//相对于左下角,起始位置相对无平移,终点分别向右向下移动 1倍的宽度与高度,效果即为右下角平移
animation =
        Tween(begin: Offset(0, 0), end: Offset(1, 1)).animate(controller);

在这里插入图片描述


3 垂直向下平移
animation =
        Tween(begin: Offset(0, 0), end: Offset(0, 1)).animate(controller);
在这里插入代码片

在这里插入图片描述

4 flutter 无限循环的平移动画

widget 平移到终点后,再回到起点再次发起平移
关键代码

  //将动画重置到开始前的状态
 controller.reset();
 //开始执行
 controller.forward();

在这里插入图片描述

  controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    //动画开始、结束、向前移动或向后移动时会调用StatusListener
    controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
       //动画从 controller.forward() 正向执行 结束时会回调此方法
        print("status is completed");
        //将动画重置到开始前的状态
        controller.reset();
        //开始执行
        controller.forward();
      } else if (status == AnimationStatus.dismissed) {
       //动画从 controller.reverse() 反向执行 结束时会回调此方法
        print("status is dismissed");
        //controller.forward();
      } else if (status == AnimationStatus.forward) {
        print("status is forward");
        //执行 controller.forward() 会回调此状态
      } else if (status == AnimationStatus.reverse) {
        //执行 controller.reverse() 会回调此状态
        print("status is reverse");
      }
    });
    //begin: Offset.zero, end: Offset(1, 0) 以左下角为参考点,相对于左下角坐标 x轴方向向右 平移执行动画的view 的1倍 宽度,
    // y轴方向不动,也就是水平向右平移

    //begin: Offset.zero, end: Offset(1, 1) 以左下角为参考点,相对于左下角坐标 x轴方向向右 平移执行动画的view 的1倍 宽度,
    // y轴方向 向下 平衡执行动画view 的1倍的高度,也就是向右下角平移了

    //begin: Offset(1, 0), end: Offset(1, 1) 在构建布局页面的时候,执行动画的view 会先相对于自身左下角水平向右移动 执行动画的view 的1倍 宽度,
    //动画开始后 再次 移动到 end: Offset(1, 1)
    animation =
        Tween(begin: Offset(0, 0), end: Offset(0, 1)).animate(controller);

执行动画的widget

  //平移
  Widget buildSlideTransition() {
    return Center(
      child: SlideTransition(
        position: animation,
        //将要执行动画的子view
        child: Container(
          width: 200,
          height: 200,
          color: Colors.grey,
        ),
      ),
    );
  }


动画执行到终点后,再由终点反向回到起点
在这里插入图片描述

    controller =
        AnimationController(duration: const Duration(seconds: 2), vsync: this);
    //动画开始、结束、向前移动或向后移动时会调用StatusListener
    controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        //动画从 controller.forward() 正向执行 结束时会回调此方法
        print("status is completed");
        //将动画重置到开始前的状态
        controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        //动画从 controller.reverse() 反向执行 结束时会回调此方法
        print("status is dismissed");
        controller.forward();
      } else if (status == AnimationStatus.forward) {
        print("status is forward");
        //执行 controller.forward() 会回调此状态
      } else if (status == AnimationStatus.reverse) {
        //执行 controller.reverse() 会回调此状态
        print("status is reverse");
      }
    });
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Flutter 底部弹出动画可以通过使用 BottomSheet widget 和 AnimatedContainer widget 来实现。 首先,创建一个 StatefulWidget,包含一个 bool 变量用于控制 BottomSheet 的显示和隐藏。 ``` class BottomSheetDemo extends StatefulWidget { @override _BottomSheetDemoState createState() => _BottomSheetDemoState(); } class _BottomSheetDemoState extends State<BottomSheetDemo> { bool _isVisible = false; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Bottom Sheet Demo'), ), body: Center( child: RaisedButton( child: Text('Show Bottom Sheet'), onPressed: () { setState(() { _isVisible = true; }); }, ), ), bottomSheet: _isVisible ? Container( decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 5.0, spreadRadius: 1.0, offset: Offset(0.0, -1.0), ), ], ), child: SafeArea( child: AnimatedContainer( duration: Duration(milliseconds: 300), height: _isVisible ? 200.0 : 0.0, child: Center( child: Text('This is a Bottom Sheet'), ), ), ), ) : null, ); } } ``` 在上面的代码中,我们使用了一个 RaisedButton 来触发 Bottom Sheet 的显示,当用户点击按钮后,我们将 _isVisible 变量设置为 true,Bottom Sheet 就会显示出来。 Bottom Sheet 的内容是一个 AnimatedContainer,它的高度可以通过修改 _isVisible 变量来控制。在 AnimatedContainer 中,我们设置了一个动画时长为 300 毫秒,当 _isVisible 变量变化时,高度会从 0.0 到 200.0 进行动画过渡。 在 Bottom Sheet 的外部,我们使用了一个 Container 来包装它,并设置了一些阴影效果和背景颜色。我们还使用了 SafeArea 来确保 Bottom Sheet 不会被设备的导航栏遮挡。 通过这种方式,我们可以很容易地实现一个底部弹出动画效果。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

早起的年轻人

创作源于分享

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值