flutter 動(dòng)畫

一捕捂、隱式(全自動(dòng))動(dòng)畫

所謂隱式動(dòng)畫就是只需要設(shè)置動(dòng)畫目標(biāo)窟勃,過程控制由系統(tǒng)實(shí)現(xiàn)

一般是簡(jiǎn)單點(diǎn)的動(dòng)畫,比如只是簡(jiǎn)單的寬高變化遥皂。當(dāng)然使用簡(jiǎn)單不代表功能就簡(jiǎn)單力喷,下面會(huì)有體現(xiàn)

沒有循環(huán)重播刽漂,不用隨時(shí)中斷,沒有多方協(xié)調(diào)冗懦,就是從開始運(yùn)行到結(jié)束爽冕。

這種動(dòng)畫一般就是隱式動(dòng)畫仇祭,使用flutter提供的api披蕉,隱式動(dòng)畫一般是Animated...開頭。所以乌奇,便于學(xué)習(xí)記憶

還可以自定義隱式動(dòng)畫:TweenAnimationBuilder

AnimatedContainer

\color{red} {該組件是處理盒子級(jí)別動(dòng)畫的}

動(dòng)畫盒子没讲,是作用到盒子屬性上的,所以盒子有的一些屬性礁苗,是可以動(dòng)畫效果的爬凑。。但是每個(gè)widget都有自己的管理试伙,所以嘁信,如果想實(shí)現(xiàn)盒子里widget的動(dòng)畫就需要?jiǎng)e的方式了

實(shí)現(xiàn)很簡(jiǎn)單,就兩行代碼疏叨,AnimatedContainer潘靖,duration變量。flutter會(huì)隱式的幫我們處理動(dòng)畫過程蚤蔓。

實(shí)現(xiàn)簡(jiǎn)單卦溢,但是功能可不簡(jiǎn)單,container有個(gè)decoration屬性秀又,該屬性能實(shí)現(xiàn)的功能是很豐富的单寂。所以,只要是盒子這個(gè)級(jí)別的所有變化都是可以動(dòng)畫的

不同控件間切換的過渡動(dòng)畫:AnimatedSwitcher

\color{red} {該組件是在子組件發(fā)生變化時(shí)候處理動(dòng)畫的}

依然是個(gè)widget吐辙,是個(gè)盒子宣决,但是該盒子是用于處理內(nèi)部child組件切換時(shí)候動(dòng)畫的。

也是只有一個(gè)屬性:duration昏苏。flutter會(huì)隱式幫我們處理動(dòng)畫過程

但是當(dāng)子組件沒有變化的時(shí)候尊沸,就沒有動(dòng)畫了

比如:AnimatedSwitcher內(nèi)的child組件是個(gè)text,text內(nèi)容有變化的時(shí)候捷雕,就不會(huì)有動(dòng)畫椒丧,這是因?yàn)閒lutter判斷child子組件沒有發(fā)生變化,就沒有觸發(fā)動(dòng)畫過程

所以救巷,只需要給組件設(shè)置一個(gè)key即可壶熏。可以如下簡(jiǎn)單的設(shè)置一下:UniqueKey浦译,表示自己唯一的key

key: UniqueKey()

demo

return AnimatedContainer(
      duration: const Duration(milliseconds: 300),
      width: 200,
      height: 300,
      child: AnimatedSwitcher(
          duration: const Duration(milliseconds: 400),
          //當(dāng)內(nèi)容有變化的時(shí)候就會(huì)觸發(fā)動(dòng)畫
          child: Text('content', key: UniqueKey(),),
          // 豐富的動(dòng)畫控制
          transitionBuilder: (child, animation) {
            return FadeTransition(
              opacity: animation,
              child: ScaleTransition(
                scale: animation,
                child: child,
              ),
            );
          }
      ),
    );
AnimatedSwitcher.gif

其他的一些可以自行嘗試

一般就是Animated...開頭的動(dòng)畫組件

  • AnimatedOpacity
  • AnimatedPadding
  • ...

另外動(dòng)畫默認(rèn)是線性變化的棒假,動(dòng)畫有個(gè)curve屬性溯职,可以自行嘗試

curves官方文檔

TweenAnimationBuilder

\color{red} {補(bǔ)間動(dòng)畫,重點(diǎn)在于開始和結(jié)束值帽哑,flutter幫我們補(bǔ)幀}

\color{green} {代碼流程:基于設(shè)備幀率谜酒,比如60幀,那在duration內(nèi)flutter幫我們從begin值到end值補(bǔ)} \color{green} {上58幀圖畫妻枕。builder回調(diào)1s內(nèi)會(huì)被調(diào)60次僻族,把tween當(dāng)前值傳給builder用于控制ui當(dāng)前狀態(tài)}

\color{blue} {tip:}
\color{blue} {1、補(bǔ)間動(dòng)畫每次都是從當(dāng)前值到end的動(dòng)畫過程屡谐,所以begin值就相當(dāng)于一個(gè)動(dòng)畫初始值了述么。}
\color{blue} {2、tween值設(shè)置的時(shí)候要結(jié)合具體動(dòng)畫控制的范圍愕掏。比如Opacity是從0~1度秘,rotate是0~6.28。}

demo

return TweenAnimationBuilder(
        tween: Tween(begin: 0.0, end: 1.0),
        duration: const Duration(seconds: 2),
        builder: (context, double value, widget) {
          return Opacity(
            opacity: value,
            child: Container(
              width: 200,
              height: 300,
              color: Colors.red,
            ),
          );
        }
    );

補(bǔ)充:平移動(dòng)畫饵撑,offset可以直接寫到tween里

二剑梳、顯示(手動(dòng)控制)動(dòng)畫

\color{red} {隱式動(dòng)畫的流程是系統(tǒng)控制的,大部分工作都是由系統(tǒng)來做的滑潘。只是需要我們?cè)O(shè)置begin和end值垢乙。但是有些是}
\color{red} {需要?jiǎng)赢嬕恢边\(yùn)行,或者其他的需要我們來控制更多的流程众羡,就需要顯示動(dòng)畫了侨赡,我們手動(dòng)控制動(dòng)畫流程}

一般我們使用AnimationController的時(shí)候,直接在as中鍵入stanim使用模板代碼:

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

  @override
  _xxxState createState() => _xxxState();
}

class _xxxState extends State<xxx> with SingleTickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this);
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

vsync:垂直信號(hào)粱侣,由于不同設(shè)備刷新頻率不一樣羊壹,告訴系統(tǒng)何時(shí)同步動(dòng)畫狀態(tài)。with SingleTickerProviderStateMixin齐婴。vsync:this即可

  • controller是什么油猫?

動(dòng)畫控制器,是跟系統(tǒng)有綁定的關(guān)系柠偶,通過vsync:this實(shí)現(xiàn)屏幕刷新回調(diào)builder回調(diào)情妖。所以動(dòng)畫的實(shí)現(xiàn)最關(guān)心的是_controller持續(xù)的變動(dòng)以及builder回調(diào)刷新,具體的動(dòng)畫控制可以自行實(shí)現(xiàn)诱担,用Tween修改動(dòng)畫范圍

比如我們使用RotationTransition的時(shí)候turns參數(shù)就可以傳_controller毡证,turns的入?yún)⒕涂梢杂肁nimationController做一個(gè)映射,自己來控制轉(zhuǎn)的圈數(shù):turns:_controller.drive(Tween(end: 4)) 這樣實(shí)現(xiàn)了_controller的duration內(nèi)旋轉(zhuǎn)4圈

同理其他...Transition以及AnimatedTransition也一樣可以這樣用蔫仙。比如FadeTransition料睛,opacity就可以直接用_controller。

另外可以addListener監(jiān)聽它的值變化,也可以用.value獲取動(dòng)畫過程中當(dāng)前值

  • turns傳的controller怎么會(huì)是個(gè)double呢恤煞?

上面說的RotatationTransition屎勘,turns參數(shù)怎么可以用_controller呢?它是繼承自extends Animation<double>的居扒。

  • ?
    • 比如ScaleTransition概漱,scale入?yún)ween(),可以用_controller.drive(Tween())包裝為Animation<double>類型喜喂。作用就是_controller的duration范圍內(nèi)Tween補(bǔ)幀縮放范圍.

    • 比如AlignTransition瓤摧,alignment入?yún)⑹茿nimation<AlignmentGeometry>類型,也可以用_controller.drive()驅(qū)動(dòng)

    return SlideTransition(
        position:_controller.drive(Tween(begin: Offset(0, 0), end: Offset(1, 1))),
    );
    return AlignTransition(
      alignment: _controller.drive(Tween(begin: Alignment.topLeft, end: Alignment.bottomRight)),
      child: const Text("d"),
    );
  • ticker是什么夜惭?

英文釋義是嘀嗒聲姻灶,形象的表述為屏幕刷新頻率,屏幕要刷新一幀的時(shí)候就發(fā)一個(gè)tick

AnimationController初始化的時(shí)候設(shè)置的duration范圍诈茧,有幾種控制方式:

1、初始化controller時(shí)候捂掰,設(shè)置lowerBound敢会,upperBound

2、scale:_controller.drive(Tween(begin:0.0, end:1.0))这嚣。

這種方式解決的是將Tween<double>轉(zhuǎn)為Animation<double>

3鸥昏、還有種寫法:交錯(cuò)動(dòng)畫

Tween(begin:Offset(0, -0.5), end:Offset(0, 8))
.chain(CurveTween(curve: Curves.elasticInOut))
.chain(CurveTween(curve: Interval(0.0, 0.2)))
.animate(_controller)

chain可以理解為一個(gè)函數(shù),就好比g(h(f(x)))姐帚,函數(shù)嵌套吏垮,_controller就像是動(dòng)畫的持續(xù)過程,這個(gè)是跟屏幕刷新有關(guān)罐旗,但是可以通過多函數(shù)復(fù)合作用于實(shí)際動(dòng)畫效果膳汪。比如上面的代碼:offset移動(dòng)和移動(dòng)速度曲線同時(shí)作用于動(dòng)畫過程,就有了從開始到結(jié)束沿移動(dòng)速度曲線進(jìn)行移動(dòng)的動(dòng)畫效果

tween-chain.gif

自定義顯示動(dòng)畫:AnimatedBuidler

自定義顯示動(dòng)畫九秀,一是把動(dòng)畫控制交給AnimationController遗嗽,二是可以做一些性能優(yōu)化。比如把動(dòng)畫渲染過程中不需要重繪的組件交給AnimatedBuidler

@override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      //_controller控制內(nèi)持續(xù)的調(diào)用builder
      builder: (context, child) {
        //每次調(diào)用builder鼓蜒,內(nèi)部所有組件都會(huì)重新渲染痹换,注意考慮優(yōu)化性能
        return Opacity(
          //這里value超過1也沒關(guān)系,有自動(dòng)糾錯(cuò)機(jī)制都弹。并不會(huì)報(bào)錯(cuò)娇豫。透明度是0~1,如果超過1就還是1不透明的效果
          opacity: _controller.value,
          child: Container(
            width: 300,
            height: 200 + 100 * _controller.value,
            color: Colors.red,
            child: child,
          ),
        );
      },
      //動(dòng)畫執(zhí)行過程中畅厢,不需要變化的部分可以傳給AnimatedBuilder冯痢,
      // 每次builder回調(diào)時(shí)候會(huì)再傳出來,這樣就避免了child部分的重新渲染
      child: const Center(
        child: Text(
          "hello",
          style: TextStyle(fontSize: 24),
        ),
      ),
    );
  }

三、其他動(dòng)畫

Flutter動(dòng)畫背后的機(jī)制和原理

Hero動(dòng)畫

hero-animation.gif

動(dòng)畫轉(zhuǎn)場(chǎng)更絲滑

但是貌似好像看不出hero動(dòng)畫的牛逼之處系羞,下面再看個(gè)例子:

hero-animation2.gif
hero-animation3.gif

hero動(dòng)畫有個(gè)特點(diǎn)郭计,就是觸發(fā)那一刻就變?yōu)槟繕?biāo)ui然后開始動(dòng)畫

功能強(qiáng)大,使用簡(jiǎn)單椒振,只需要在開始和目標(biāo)ui上包括Hero并設(shè)置相同唯一的tag即可

直接操作底層的CustomPaint

嵌入式lottie昭伸、Rive/Flare插件動(dòng)畫

體驗(yàn)了一下Rive在線動(dòng)畫平臺(tái),跟lottie是差不多的澎迎,支持的平臺(tái)也很全庐杨。動(dòng)畫制作交給美工就行了,具體實(shí)現(xiàn)夹供,都是加載json灵份。提供的都有插件.

https://rive.app.可以體驗(yàn)一下,制作一個(gè)簡(jiǎn)單的動(dòng)畫哮洽,設(shè)置時(shí)間節(jié)點(diǎn)的關(guān)鍵幀填渠,動(dòng)畫也有補(bǔ)幀動(dòng)畫的感覺

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鸟辅,隨后出現(xiàn)的幾起案子氛什,更是在濱河造成了極大的恐慌,老刑警劉巖匪凉,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件枪眉,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡再层,警方通過查閱死者的電腦和手機(jī)贸铜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來聂受,“玉大人蒿秦,你說我怎么就攤上這事〗确梗” “怎么了渤早?”我有些...
    開封第一講書人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瘫俊。 經(jīng)常有香客問我鹊杖,道長(zhǎng),這世上最難降的妖魔是什么扛芽? 我笑而不...
    開封第一講書人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任骂蓖,我火速辦了婚禮,結(jié)果婚禮上川尖,老公的妹妹穿的比我還像新娘登下。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開白布被芳。 她就那樣靜靜地躺著缰贝,像睡著了一般。 火紅的嫁衣襯著肌膚如雪畔濒。 梳的紋絲不亂的頭發(fā)上剩晴,一...
    開封第一講書人閱讀 52,475評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音侵状,去河邊找鬼赞弥。 笑死,一個(gè)胖子當(dāng)著我的面吹牛趣兄,可吹牛的內(nèi)容都是我干的绽左。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼艇潭,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼拼窥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起暴区,我...
    開封第一講書人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤闯团,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后仙粱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡彻舰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年伐割,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刃唤。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡隔心,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出尚胞,到底是詐尸還是另有隱情硬霍,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布笼裳,位于F島的核電站唯卖,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏躬柬。R本人自食惡果不足惜拜轨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望允青。 院中可真熱鬧橄碾,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拒垃,卻和暖如春停撞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背恶复。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工怜森, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人谤牡。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓副硅,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親翅萤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子恐疲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

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

  • Flutter的動(dòng)畫體系是怎么運(yùn)作的,各組件之間的關(guān)聯(lián)關(guān)系及原理什么套么,隱式動(dòng)畫培己、顯式動(dòng)畫怎么區(qū)分,本文將會(huì)進(jìn)行詳細(xì)...
    whqfor閱讀 2,024評(píng)論 0 6
  • 本文通過拆解 Flutter 中動(dòng)畫的實(shí)現(xiàn)方式以及原理來介紹動(dòng)畫實(shí)現(xiàn)的整個(gè)過程零蓉。 1. 動(dòng)畫四要素 動(dòng)畫在各個(gè)平臺(tái)...
    Meandni閱讀 2,021評(píng)論 0 3
  • 概述在Flutter的使用過程中,我們總是會(huì)調(diào)用addListener方法添加每一幀的回調(diào)監(jiān)聽穷缤,并且動(dòng)畫都是體現(xiàn)在...
    Horps閱讀 812評(píng)論 0 2
  • 對(duì)動(dòng)畫系統(tǒng)而言敌蜂,為了實(shí)現(xiàn)動(dòng)畫,它需要做三件事兒:1.確定畫面變化的規(guī)律津肛;2.根據(jù)這個(gè)規(guī)律章喉,設(shè)定動(dòng)畫周期,啟動(dòng)動(dòng)畫身坐;...
    Cat_uncle閱讀 1,057評(píng)論 0 0
  • Flutter動(dòng)畫類型 動(dòng)畫分為兩類:基于tween或基于物理的掀亥。以下部分解釋了這些術(shù)語的含義撞反,并指出您可以在其中...
    蓋世英雄_ix4n04閱讀 6,176評(píng)論 0 2