Flutter(十七)——组合动画

Staggered Animations

Staggered Animations就是交错动画,也可以称之为组合动画。在实际的动画使用过程中,动画可能并不是由一个单一方式呈现的。渐变,位移,缩放等都是基础的动画,而我们有时候需要把这些基础的动画组合起来,使其成为一个组合动画,即交错动画。(下图为本文最终实现效果)

组合动画

在Android开发中,是通过AnimationController来实现这种交错动画的。在Flutter开发中,也沿用了名为AnimationController的类来实现。

组合动画的代码实现

对于如何在Flutter开发中,写交错动画,我们可以通过AnimationController把动画组合在一起,然后分别设置其动画的参数即可。

对于AnimationController来说,控制器的值Tween必须属于(0.0,1.0)。也就是说,组合动画的所有间隔必须在0到1的数字之间进行,有了这个思路,我们来实践实现其交错动画(组合动画),代码如下:

import 'package:flutter/scheduler.dart' show timeDilation;
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin{
  AnimationController controller;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller=AnimationController(duration: const Duration(milliseconds: 2000),vsync: this);//初始化,动画控制器,每个动画都是执行2秒
  }

  @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    controller.dispose();//销毁释放
  }

  Future<void> _playAnimation() async{
    try{
      await controller.forward().orCancel;//开始
      await controller.reverse().orCancel;//反向
    }on TickerCanceled{

    }
  }

  @override
  Widget build(BuildContext context) {
    timeDilation=10.0;
    return Scaffold(
      appBar: AppBar(
        title: Text("组合动画"),
      ),
      body: GestureDetector(
        behavior: HitTestBehavior.opaque,//自己处理事件
        onTap: (){
          _playAnimation();
        },
        child: Center(
          child: Container(
            width: 300.0,
            height: 300.0,
            decoration: BoxDecoration(
              color: Colors.black.withOpacity(0.1),
              border: Border.all(
                color: Colors.black.withOpacity(0.5),
              ),
            ),
            child: StaggedAnimation(controller: controller.view,),
          ),
        ),
      ),
    );
  }
}

class StaggedAnimation extends StatelessWidget{
  //Curves.ease一种三次动画曲线,速度快,结束慢
  final Animation<double> controller;
  final Animation<double> bezier;//透明度渐变
  final Animation<double> width;//宽度变化
  final Animation<double> height;//高度变化
  final Animation<EdgeInsets> drift;//位移变化
  final Animation<BorderRadius> borderRadius;//圆角变化
  final Animation<Color> color;//颜色变化
  StaggedAnimation({Key key,this.controller}):
        bezier=Tween<double>(
          begin: 0.0,
          end: 1.0,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.0, 0.1,curve: Curves.ease),
          )
        ),
        width=Tween<double>(
          begin: 50.0,
          end: 150.0,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.125,0.250,curve: Curves.ease),
          )
        ),
        height=Tween<double>(
          begin: 50.0,
          end: 150.0,
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.250,0.375,curve: Curves.ease),
          ),
        ),
        drift=EdgeInsetsTween(
          begin: const EdgeInsets.only(bottom: 16.0),
          end: const EdgeInsets.only(bottom: 75.0),
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.375,0.5,curve: Curves.ease),
          ),
        ),
        borderRadius=BorderRadiusTween(
          begin: BorderRadius.circular(4.0),
          end: BorderRadius.circular(75.0),
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.5,0.75,curve: Curves.ease),
          ),
        ),
        color=ColorTween(
          begin: Colors.indigo[100],
          end: Colors.orange[400],
        ).animate(
          CurvedAnimation(
            parent: controller,
            curve: Interval(0.75,1.0,curve: Curves.ease),
          ),
        ),
        super(key:key);

  Widget _buildAnimation(BuildContext context,Widget child){
    return Container(
      padding: drift.value,
      alignment: Alignment.bottomCenter,
      child: Opacity(//透明组件
        opacity: bezier.value,
        child: Container(
          width: width.value,
          height: height.value,
          decoration: BoxDecoration(
            color: color.value,
            border: Border.all(
                color: Colors.indigo[300],
                width: 3.0
            ),
            borderRadius: borderRadius.value,
          ),
        ),
      ),
    );
  }


  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      builder: _buildAnimation,
      animation: controller,
    );
  }
}

上面代码使用的是AnimatedBuilder,这样可以不用去显式的去添加addlistener,节省很多代码,不懂的可以回顾前面的内容,其他的代码不用多说,还有,dart异步在第三篇dart语言中有讲到,这里就不过多的赘述了,这段组合动画实现的效果如首图所示。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flutte中可以使用Flutter动画库来创建聊天语音播放动画。在Flutter中,动画可以通过使用AnimationController和Tween来实现。 首先,需要创建一个AnimationController对象来控制动画的进度。可以设置动画的持续时间和一个曲线来定义动画的速度曲线。然后,可以使用Tween来定义动画的初始值和结束值。 在聊天语音播放动画中,可以将AnimationController对象与某个按钮或触发器关联起来,以便在触发器被点击或滑动时开始动画。可以使用addStatusListener来监听动画的状态改变,例如动画开始、结束或循环等。 在动画开始时,可以通过调用AnimationController的forward方法来启动动画。然后,在动画的每一帧中,可以使用Tween的animate方法来根据动画的进度值获取当前的属性值。可以使用AnimatedBuilder小部件来包裹需要应用动画的相关小部件,并在builder回调中更新这些小部件的属性。 在聊天语音播放动画中,可以使用AnimatedContainer来实现音量动画效果,通过设置container的高度或宽度的变化来表示音量的大小。也可以结合使用AnimatedOpacity来实现透明度的变化效果,以模拟语音播放的动态效果。 最后,在动画播放结束时,可以使用AnimationController的reverse方法来反向播放动画,或者使用reset方法来复位动画的进度。 综上所述,通过使用Flutter动画库中的AnimationController、Tween和相关小部件,可以实现聊天语音播放动画,给用户带来更加生动和交互性的体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李元静

您的鼓励就是我创作的动力

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

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

打赏作者

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

抵扣说明:

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

余额充值