Flutter(十八)——支付宝咻一咻动画实践

六月ゝ 毕业季﹏ 提交于 2020-02-09 18:26:08

咻一咻设计

对于支付宝咻一咻功能,是在2016年的时候上线到支付宝的,那个时候好像是专门为了集五福而设计的功能,现在肯定已经不在了,不过这也是一个动画功能,对于实践Flutter动画在合适不过了。(下图是我们最后实现的效果)
在这里插入图片描述
首先,我们来看看上图,具体有那些设计,比如它有三个圆圈匀速放大的动画,其次,中间有一个按钮,用户点击之后,就会出现如上动画的效果,ok,也就是这么多,弄清楚几个动画,我们就来实践一下。

代码实现咻一咻

三个动画的实现

对于代码的实现,我们肯定首先实现其3个动画,前面已经讲过了,要实现这种动画的效果,会用到AnimationController,Animation以及Tween,下面我们直接上代码:

 AnimationController controller;
  Animation<double> animation1,animation2,animation3;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    controller=AnimationController(duration: widget.duration,vsync: this)..repeat();//初始化,动画控制器执行实践为2秒
    animation1=Tween(
        begin: 0.0,
        end: 1.0)
        .animate(
        CurvedAnimation(
            parent: controller,
            curve: const Interval(0.0, 0.5,curve: Curves.linear)))
      ..addListener(
              ()=>setState(()=><String,void>{})
      );//线性动画
    animation2=Tween(
        begin: 0.0,
        end: 1.0)
        .animate(
        CurvedAnimation(
            parent: controller,
            curve: const Interval(0.25, 0.75,curve: Curves.linear)))
      ..addListener(
              ()=>setState(()=><String,void>{})
      );//线性动画
    animation3=Tween(
        begin: 0.0,
        end: 1.0)
        .animate(
        CurvedAnimation(
            parent: controller,
            curve: const Interval(0.5, 1.0,curve: Curves.linear)))
      ..addListener(
              ()=>setState(()=><String,void>{})
      );//线性动画
  }

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

每次操作动画,记得控制器一定要销毁,上面有三个动画,分别是(0.0,0.5),(0.25,0.75),(0.5,1.0)三段动画,都是Curves.linear匀速效果。

构建圆

既然我们写好的动画,动画肯定需要执行在组件之上,而我们放大的效果就是圆边框组件,所以我们需要实现一个圆边框组件,代码如下:

Widget _itemBuilder(index){
    return SizedBox.fromSize(//创建具有指定大小的框
      size: Size.square(widget.size),//宽高一致
      child: widget.itemBuidler!=null?widget.itemBuidler(context,index):DecoratedBox(
        decoration: BoxDecoration(
         shape: BoxShape.circle,//圆
         border: Border.all(color: widget.color,width: widget.borderWidth), //指定边框颜色和宽
        ),
      ),
    );

透明效果

咻一咻不仅仅只有放大的动画效果,在放大的过程之中,圆圈也会慢慢淡去,所以我们还需要实现Opacity组件,而且圆圈都是居中显示叠加的效果,所以我们需要使用到Stack组件,代码如下:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("咻一咻功能实现"),),
      body: Center(
        child: Stack(
          alignment: Alignment.center,
          children: <Widget>[
            CircleAvatar(
              backgroundImage: AssetImage("assets/timg.jpg"),
              radius: 30.0,
            ),
            Opacity(
              opacity: 1.0-animation1.value,
              child: Transform.scale(scale: animation1.value,child: _itemBuilder(0),),
            ),
            Opacity(
              opacity: 1.0-animation2.value,
              child: Transform.scale(scale: animation2.value,child: _itemBuilder(1),),
            ),
            Opacity(
              opacity: 1.0-animation3.value,
              child: Transform.scale(scale: animation3.value,child: _itemBuilder(2),),
            ),
          ],
        ),
      ),
    );
  }

Transform.scale是放大的方法,opacity: 1.0-animation3.value,监测透明度的变化,从大到小慢慢消失,中间还有一个按钮组件CircleAvatar,如果想通过点击实现也可以套一层前面介绍的手势组件GestureDetector,监听onTap()属性就行。

到这里,我们就完成了支付宝咻一咻的所有代码,相信用Flutter实现起来还是非常简单的,当然,还有其他代码和一些参数,如下:

class MyHomePage extends StatefulWidget {
  MyHomePage({
    Key key,
    this.title,
    this.size=500.0,
    this.borderWidth=16.0,
    this.itemBuidler,
    this.duration=const Duration(milliseconds: 1800),
    this.color=Colors.orange,
  }) : assert(color!=null),
        assert(size!=null),
        assert(borderWidth!=null),
        super(key: key);

  final String title;
  final double size;
  final double borderWidth;
  final Color color;
  final Duration duration;
  final IndexedWidgetBuilder itemBuidler;
  @override
  _MyHomePageState createState() => _MyHomePageState();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!