Flutter 之 交織動(dòng)畫(三十五)

我們可能會(huì)需要一些復(fù)雜的動(dòng)畫铅匹,這些動(dòng)畫可能由一個(gè)動(dòng)畫序列或重疊的動(dòng)畫組成,比如:有一個(gè)柱狀圖,需要在高度增長(zhǎng)的同時(shí)改變顏色汉规,等到增長(zhǎng)到最大高度后,我們需要在X軸上平移一段距離驹吮≌胧罚可以發(fā)現(xiàn)上述場(chǎng)景在不同階段包含了多種動(dòng)畫,要實(shí)現(xiàn)這種效果碟狞,使用交織動(dòng)畫(Stagger Animation)會(huì)非常簡(jiǎn)單啄枕。交織動(dòng)畫需要注意以下幾點(diǎn):

  1. 要?jiǎng)?chuàng)建交織動(dòng)畫,需要使用多個(gè)動(dòng)畫對(duì)象(Animation)族沃。
  2. 一個(gè)AnimationController控制所有的動(dòng)畫對(duì)象频祝。
  3. 給每一個(gè)動(dòng)畫對(duì)象指定時(shí)間間隔(Interval)(默認(rèn)情況下 時(shí)間間隔是0.0~1.0)

所有動(dòng)畫都由同一個(gè)AnimationController驅(qū)動(dòng)泌参,無論動(dòng)畫需要持續(xù)多長(zhǎng)時(shí)間,控制器的值必須在0.0到1.0之間常空,而每個(gè)動(dòng)畫的間隔(Interval)也必須介于0.0和1.0之間沽一。對(duì)于在間隔中設(shè)置動(dòng)畫的每個(gè)屬性,需要分別創(chuàng)建一個(gè)Tween用于指定該屬性的開始值和結(jié)束值漓糙。也就是說0.0到1.0代表整個(gè)動(dòng)畫過程铣缠,我們可以給不同動(dòng)畫指定不同的起始點(diǎn)和終止點(diǎn)來決定它們的開始時(shí)間和終止時(shí)間。

示例1
實(shí)現(xiàn)一個(gè)透明度變化昆禽、大小變化蝗蛙、顏色變化、旋轉(zhuǎn)的動(dòng)畫


class MSStaggerAnimationRouter1 extends StatefulWidget {
  const MSStaggerAnimationRouter1({Key? key}) : super(key: key);

  @override
  State<MSStaggerAnimationRouter1> createState() =>
      _MSStaggerAnimationRouter1State();
}

class _MSStaggerAnimationRouter1State extends State<MSStaggerAnimationRouter1>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> opacityAnimation;
  late Animation<double> transformAnimation;
  late Animation<double> sizeAnimation;
  late Animation<Color?> colorAnimation;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 5));

    opacityAnimation = Tween(begin: 0.0, end: 1.0)
        .animate(CurvedAnimation(parent: _controller, curve: Curves.linear));
    transformAnimation = Tween(begin: 0.0, end: 2 * pi)
        .animate(CurvedAnimation(parent: _controller, curve: Curves.linear));
    sizeAnimation = Tween(begin: 0.0, end: 300.0)
        .animate(CurvedAnimation(parent: _controller, curve: Curves.bounceIn));
    colorAnimation = ColorTween(begin: Colors.amber, end: Colors.red).animate(
        CurvedAnimation(parent: _controller, curve: Curves.decelerate));

    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Opacity(
              opacity: opacityAnimation.value,
              child: Transform(
                transform: Matrix4.rotationZ(transformAnimation.value),
                alignment: Alignment(0, 0), // 旋轉(zhuǎn)中心點(diǎn)
                child: Container(
                  width: sizeAnimation.value,
                  height: sizeAnimation.value,
                  color: colorAnimation.value,
                ),
              ),
            );
          },
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}
 
36.gif

示例2
實(shí)現(xiàn)一個(gè)柱狀圖增長(zhǎng)的動(dòng)畫:

開始時(shí)高度從0增長(zhǎng)到300像素醉鳖,同時(shí)顏色由綠色漸變?yōu)榧t色捡硅;這個(gè)過程占據(jù)整個(gè)動(dòng)畫時(shí)間的60%。
高度增長(zhǎng)到300后辐棒,開始沿X軸向右平移100像素病曾;這個(gè)過程占用整個(gè)動(dòng)畫時(shí)間的40%。


class MSStaggerAnimationRouter2 extends StatefulWidget {
  const MSStaggerAnimationRouter2({Key? key}) : super(key: key);

  @override
  State<MSStaggerAnimationRouter2> createState() =>
      _MSStaggerAnimationRouter2State();
}

class _MSStaggerAnimationRouter2State extends State<MSStaggerAnimationRouter2>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> heightAnimation;
  late Animation<Color?> colorAnimation;
  late Animation<EdgeInsets?> paddingAnimation;

  @override
  void initState() {
    super.initState();
    _controller =
        AnimationController(vsync: this, duration: Duration(seconds: 3));
    // Interval 間隔漾根,前60%的動(dòng)畫時(shí)間
    heightAnimation = Tween(begin: 0.0, end: 300.0).animate(CurvedAnimation(
        parent: _controller, curve: Interval(0.0, 0.6, curve: Curves.linear)));
    colorAnimation = ColorTween(begin: Colors.green, end: Colors.red).animate(
        CurvedAnimation(
            parent: _controller,
            curve: Interval(0.0, 0.6, curve: Curves.ease)));
    // Interval 間隔泰涂,后40%的動(dòng)畫時(shí)間
    paddingAnimation = Tween<EdgeInsets>(
            begin: EdgeInsets.only(left: 0.0), end: EdgeInsets.only(left: 100))
        .animate(
            CurvedAnimation(parent: _controller, curve: Interval(0.6, 1.0)));
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          height: 300,
          alignment: Alignment(0, 1),
          child: AnimatedBuilder(
            animation: _controller,
            builder: (context, child) {
              return Padding(
                padding: paddingAnimation.value!,
                child: Container(
                  height: heightAnimation.value,
                  width: 50,
                  color: colorAnimation.value,
                ),
              );
            },
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.play_circle),
        onPressed: () {
          if (_controller.isAnimating) {
            _controller.stop();
          } else {
            if (_controller.status == AnimationStatus.dismissed ||
                _controller.status == AnimationStatus.forward) {
              _controller.forward();
            } else {
              _controller.reverse();
            }
          }
        },
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }
}

37.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辐怕,隨后出現(xiàn)的幾起案子逼蒙,更是在濱河造成了極大的恐慌,老刑警劉巖寄疏,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件是牢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡陕截,警方通過查閱死者的電腦和手機(jī)驳棱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來农曲,“玉大人社搅,你說我怎么就攤上這事∪楣妫” “怎么了形葬?”我有些...
    開封第一講書人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)暮的。 經(jīng)常有香客問我笙以,道長(zhǎng),這世上最難降的妖魔是什么冻辩? 我笑而不...
    開封第一講書人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任猖腕,我火速辦了婚禮拆祈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谈息。我一直安慰自己缘屹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開白布侠仇。 她就那樣靜靜地躺著轻姿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逻炊。 梳的紋絲不亂的頭發(fā)上互亮,一...
    開封第一講書人閱讀 51,482評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音余素,去河邊找鬼豹休。 笑死,一個(gè)胖子當(dāng)著我的面吹牛桨吊,可吹牛的內(nèi)容都是我干的威根。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼视乐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼洛搀!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佑淀,我...
    開封第一講書人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤留美,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后伸刃,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谎砾,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年捧颅,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了景图。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡碉哑,死狀恐怖挚币,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谭梗,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布宛蚓,位于F島的核電站激捏,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏凄吏。R本人自食惡果不足惜远舅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一闰蛔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧图柏,春花似錦序六、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至裁着,卻和暖如春繁涂,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背二驰。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工扔罪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人桶雀。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓矿酵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親矗积。 傳聞我的和親對(duì)象是個(gè)殘疾皇子全肮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容