欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android Flutter實(shí)現(xiàn)GIF動畫效果的方法詳解

 更新時間:2022年06月20日 10:41:19   作者:島上碼農(nóng)  
如果我們想對某個組件實(shí)現(xiàn)一組動效應(yīng)該怎么辦呢?本文將利用Android Flutter實(shí)現(xiàn)GIF動畫效果,文中的示例代碼講解詳細(xì),需要的可以參考一下

前言

我們之前介紹了不少有關(guān)動畫的篇章。前面介紹的動畫都是只有一個動畫效果,那如果我們想對某個組件實(shí)現(xiàn)一組動效,比如下面的效果,該怎么辦?

staggered animation

這個時候我們需要用到組合動效, Flutter 提供了交錯動畫(Staggered Animation)的方式實(shí)現(xiàn)。對于多個 Anmation 對象,可以共用一個 AnimationController,然后在不同的時間段執(zhí)行動畫效果。這就有點(diǎn)像 GIF 圖片一樣,一幀幀圖像播放實(shí)現(xiàn)連續(xù)的動畫。

交錯動畫機(jī)制

交錯動畫的實(shí)現(xiàn)基于以下幾個要點(diǎn):

  • 所有的 animation對象使用同一個 AnimationController 驅(qū)動;
  • 不管實(shí)際動畫持續(xù)的時間長度多長,動畫控制器 controller 的值必須在0-1之間;
  • 每個動畫對象都有一個0-1范圍內(nèi)的間隔(Interval);
  • 在間隔時間內(nèi),Tween 對象從起始值過渡到結(jié)束值。
  • 由 AnimationController 統(tǒng)一管理這些Tween 產(chǎn)生的 Animation 對象。

聽起來有點(diǎn)抽象,我們以一張圖來表述就清晰多了,假設(shè)我們有4個動畫對象,分別控制組件的透明度(Opacity),寬度(Width),高度(Height)和顏色(Color),交錯動畫過程如下:

時序示意圖

controller 是一個從0到1的歸一化的動畫控制,其實(shí)對應(yīng)的就是動畫時長的歸一化。然后 Opacity 透明度動效占據(jù)了0-0.25區(qū)間;Width 占據(jù)了0.25-0.5區(qū)間;Height 占據(jù)了0.5-0.75區(qū)間;最后是 Color 占據(jù)了0.75-1.0的區(qū)間。區(qū)間對應(yīng)就是動畫的時間間隔,只是每個區(qū)間內(nèi)的Tween 動畫對象的取值范圍都是0-1以控制從起始值到結(jié)束值。我們可以理解為是 AnimationController 將多個 Animation 對象按序(也可以重合)拼接起來形成復(fù)合形式的動畫。

代碼實(shí)現(xiàn)

看上面的說明是不是覺得還有些難以理解,我們來一段示例代碼就很容易明白了。下面的代碼我們定義了一個共用的_controller,然后四段動畫對象_opaticy,_width_height 和_color。其中關(guān)鍵的實(shí)現(xiàn)是使用了 Tween 對象的 animate 方法,并指定了一個 CurvedAnimation 對象作為 其parent 參數(shù)。而這個CurvedAnimation實(shí)際使用 Interval 來切分_controller 的動畫時間,從而可以將多個 Animation 對象組合起來。

import?'package:flutter/material.dart';

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

??@override
??_StaggeredAnimationDemoState?createState()?=>?_StaggeredAnimationDemoState();
}

class?_StaggeredAnimationDemoState?extends?State<StaggeredAnimationDemo>
????with?SingleTickerProviderStateMixin?{
??late?AnimationController?_controller;
??late?Animation<double>?_opacity;
??late?Animation<double>?_width;
??late?Animation<double>?_height;
??late?Animation<Color?>?_color;

??@override
??void?initState()?{
????_controller?=
????????AnimationController(duration:?Duration(seconds:?2),?vsync:?this)
??????????..addListener(()?{
????????????setState(()?{});
??????????});
????_opacity?=?Tween<double>(begin:?0.5,?end:?1.0).animate(
??????CurvedAnimation(
????????parent:?_controller,
????????curve:?Interval(
??????????0.0,
??????????0.25,
??????????curve:?Curves.easeIn,
????????),
??????),
????);
????_width?=?Tween<double>(begin:?0.0,?end:?2.0).animate(
??????CurvedAnimation(
????????parent:?_controller,
????????curve:?Interval(
??????????0.25,
??????????0.5,
??????????curve:?Curves.easeIn,
????????),
??????),
????);
????_height?=?Tween<double>(begin:?0.0,?end:?2.0).animate(
??????CurvedAnimation(
????????parent:?_controller,
????????curve:?Interval(
??????????0.5,
??????????0.75,
??????????curve:?Curves.easeIn,
????????),
??????),
????);
????_color?=?ColorTween(begin:?Colors.green,?end:?Colors.blue).animate(
??????CurvedAnimation(
????????parent:?_controller,
????????curve:?Interval(
??????????0.75,
??????????1.0,
??????????curve:?Curves.easeIn,
????????),
??????),
????);
????super.initState();
??}

??@override
??Widget?build(BuildContext?context)?{
????return?Scaffold(
??????appBar:?AppBar(
????????title:?const?Text('交錯動畫'),
??????),
??????body:?Center(
????????child:?Opacity(
??????????opacity:?_opacity.value,
??????????child:?Container(
????????????width:?100?+?100?*?_width.value,
????????????height:?100?+?100?*?_height.value,
????????????color:?_color.value,
??????????),
????????),
??????),
??????floatingActionButton:?FloatingActionButton(
????????child:?Icon(Icons.play_arrow),
????????onPressed:?()?{
??????????if?(_controller.isCompleted)?{
??????????????_controller.reverse();
????????????}?else?if?(!_controller.isAnimating)?{
??????????????_controller.forward();
??????????}
????????},
??????),
????);
??}
}

我們來看一下運(yùn)行效果,可以看到運(yùn)行的動畫過程其實(shí)就是4段動畫效果拼接來的,先是透明度改變,然后是寬度改變,再之后是高度改變,最后是顏色的改變。

運(yùn)行效果

Interval 介紹

我們來看一下關(guān)鍵的 Interval 類的介紹。

A curve that is 0.0 until [begin], then curved (according to [curve]) from 0.0 at [begin] to 1.0 at [end], then remains 1.0 past [end].

Interval 類繼承自 Curve,所不同的是,在 begin 之前曲線的值一直保持為0.0,而在 end 之后一直保持為1.0。所以可以理解為,在 AnimationController 啟動動畫后,Interval 曲線其實(shí)也已經(jīng)在繪制,只是有效的取值區(qū)間只在 begin 到 end 之間,下面就是 Interval 的一種示例曲線圖。

image.png

從 Interval 的源碼也能看出來,其中 clamp 方法限制了取值范圍,當(dāng) t <= begin 的時候取值就是0,當(dāng) t >= end的時候,取值就是1.0。

@override
double?transformInternal(double?t)?{
??assert(begin?>=?0.0);
??assert(begin?<=?1.0);
??assert(end?>=?0.0);
??assert(end?<=?1.0);
??assert(end?>=?begin);
??t?=?((t?-?begin)?/?(end?-?begin)).clamp(0.0,?1.0);
??if?(t?==?0.0?||?t?==?1.0)
????return?t;
??return?curve.transform(t);
}

總結(jié)

本篇介紹了交錯動畫的實(shí)現(xiàn)機(jī)制和示例,通過交錯動畫給了我們更多動效組合的空間,從而可以實(shí)現(xiàn)類似 GIF圖片的那種多幀組合在一起的動畫效果。

到此這篇關(guān)于Android Flutter實(shí)現(xiàn)GIF動畫效果的方法詳解的文章就介紹到這了,更多相關(guān)Android Flutter GIF動畫效果內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論