Flutter(十八)——支付寶咻一咻動畫實踐

咻一咻設計

對於支付寶咻一咻功能,是在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();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章