1.動(dòng)畫原理:在一段時(shí)間內(nèi)快速的多次改變UI外觀,由于人眼會(huì)產(chǎn)生視覺(jué)暫留所以最終看到的就是一個(gè)連續(xù)的動(dòng)畫。

創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),阜寧企業(yè)網(wǎng)站建設(shè),阜寧品牌網(wǎng)站建設(shè),網(wǎng)站定制,阜寧網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷,網(wǎng)絡(luò)優(yōu)化,阜寧網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
UI的一次改變稱為一個(gè)動(dòng)畫幀,對(duì)應(yīng)一次屏幕刷新。
FPS:幀率,每秒的動(dòng)畫幀數(shù)。
flutter動(dòng)畫分為兩類:
常見(jiàn)動(dòng)畫模式:
是一個(gè)抽象類,主要的功能是保存動(dòng)畫的值和狀態(tài)。常用的一個(gè)Animation類是Animation double ,是一個(gè)在一段時(shí)間內(nèi)依次生成一個(gè)區(qū)間之間的值的類,可以是線性或者曲線或者其他。
可以生成除double之外的其他類型值,如:Animation Color 或 Animation Size 。
是一個(gè)動(dòng)畫控制器,控制動(dòng)畫的播放狀態(tài),在屏幕刷新的每一幀,就會(huì)生成一個(gè)新的值。
包含動(dòng)畫的啟動(dòng)forward()、停止stop() 、反向播放 reverse()等方法,在給定的時(shí)間段內(nèi)線性的生成從0.0到1.0(默認(rèn)區(qū)間)的數(shù)字。
curve:描述動(dòng)畫的曲線過(guò)程。
curvedAnimation:指定動(dòng)畫的曲線。
常用Curve:
繼承自Animatable T ,表示的就是一個(gè) Animation 對(duì)象的取值范圍,只需要設(shè)置開始和結(jié)束的邊界值(值也支持泛型)。 它唯一的工作就是定義輸入范圍到輸出范圍的映射。
例如,Tween可能會(huì)生成從紅到藍(lán)之間的色值,或者從0到255。
Tween.animate:返回一個(gè)Animation。
映射過(guò)程:
1). Tween.animation通過(guò)傳入 aniamtionController 獲得一個(gè)_AnimatedEvaluation 類型的 animation 對(duì)象(基類為 Animation), 并且將 aniamtionController 和 Tween 對(duì)象傳入了 _AnimatedEvaluation 對(duì)象。
2). animation.value方法即是調(diào)用 _evaluatable.evaluate(parent)方法, 而 _evaluatable 和 parent 分別為 Tween 對(duì)象和 AnimationController 對(duì)象。
3). 這里的 animation 其實(shí)就是前面的 AnimationController 對(duì)象, transform 方法里面的 animation.value則就是 AnimationController 線性生成的 0.0~1.0 直接的值。 在 lerp 方法里面我們可以看到這個(gè) 0.0~1.0 的值被映射到了 begin 和 end 范圍內(nèi)了。
接收一個(gè)TickerProvider類型的對(duì)象,它的主要職責(zé)是創(chuàng)建Ticker。
防止屏幕外動(dòng)畫消耗資源。
[圖片上傳失敗...(image-115b94-1636441483468)]
過(guò)程:
回調(diào):
不使用addListener()和setState()來(lái)給widget添加動(dòng)畫。
使用AnimatedWidget,將widget分離出來(lái),創(chuàng)建一個(gè)可重用動(dòng)畫的widget,AnimatedWidget中會(huì)自動(dòng)調(diào)用addListener()和setState()
AnimatedModalBarrier、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition
如何渲染過(guò)渡,把渲染過(guò)程也抽象出來(lái):
AnimatedBuilder的示例包括: BottomSheet、 PopupMenu、ProgressIndicator、RefreshIndicator、Scaffold、SnackBar、TabBar。
MaterialPageRoute:平臺(tái)風(fēng)格一致的路由切換動(dòng)畫
CupertinoPageRoute:左右切換風(fēng)格
自定義:PageRouteBuilder
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)
可以同時(shí)對(duì)其新、舊子元素添加顯示、隱藏動(dòng)畫.
當(dāng)AnimatedSwitcher的child發(fā)生變化時(shí)(類型或Key不同),舊child會(huì)執(zhí)行隱藏動(dòng)畫,新child會(huì)執(zhí)行執(zhí)行顯示動(dòng)畫。
希望大家支持一下,感謝
1) PositionedTransition 是AnimatedWidget的子類,跟AnimatedBuilder一樣。主要是為了在使用動(dòng)畫的過(guò)程中減少不必要的Widget對(duì)象的創(chuàng)建工作,提高效率。
2)該類持有了一個(gè)AnimationRelativeRect的引用rect
3)在build構(gòu)建widget的時(shí)候使用了動(dòng)畫rect.value,在這里這個(gè)value就是RelativeRect對(duì)象。
那么這個(gè)RelativeRect對(duì)象是什么呢?在回答這個(gè)問(wèn)題之前先來(lái)看看官方文檔給的例子,通過(guò)這個(gè)視頻可以看出PositionedTranstion是用來(lái)干嘛的。
width="560" height="315" src=" " allowfullscreen=""
顯而易見(jiàn),PositionedTranstion通過(guò)一個(gè)特定的動(dòng)畫AnimationRelativeRect將Widget的位置從動(dòng)畫的生命周期的起始位置移到結(jié)束位置。而這個(gè)位置信息就是RelativeRect來(lái)表示,Relative相對(duì)的意思,相對(duì)誰(shuí)?相對(duì)于某個(gè)Widget,而不是相對(duì)于坐標(biāo)原點(diǎn)。 RelativeRect 有四個(gè)屬性:
所以如果我們想讓一個(gè)widget的位置(上下左右)距離RelativeRect都是100的話,就要這么寫:
有時(shí)候我們不希望某個(gè)頁(yè)面每次打開時(shí)都重新加載,比如就我們之前的Tabbar結(jié)構(gòu)的頁(yè)面,每當(dāng)我們?cè)谇袚QTab的時(shí)候都會(huì)執(zhí)行 void initState() ,這就意味著頁(yè)面每次都會(huì)重新渲染,之所以這樣就是因?yàn)槲覀兊?State 狀態(tài)沒(méi)有保存,如下圖所示:
[沒(méi)有狀態(tài)保存效果圖]
給當(dāng)前 State 類添加一個(gè)擴(kuò)展(這里就用擴(kuò)展這個(gè)詞吧,其實(shí)類似于iOS下的 Category ),一個(gè)系統(tǒng)的擴(kuò)展類 AutomaticKeepAliveClientMixin ,并重寫 wantKeepAlive 方法,讓一個(gè)普通的 State 類,具有保存狀態(tài)的能力。
在Dart語(yǔ)法中通過(guò)使用 with 關(guān)鍵字來(lái)添加擴(kuò)展:
bool get wantKeepAlive = true; 之后,當(dāng)前 State 就具備保存能力了,也就意味著重復(fù)切換Tab后, void initState() 就不會(huì)重復(fù)執(zhí)行了(由原來(lái)的 viewWillAppear() 變成了 viewDidLoad() )。
按照上面方式修改后,發(fā)現(xiàn)切換Tab后 void initState() 依然重復(fù)執(zhí)行了,這是為什么吶?這里我們看下我們之前 root_page.dart 里面是如何配置我們的tabbar結(jié)構(gòu)的:
這里我們是通過(guò)一個(gè) _viewControllers 的List,把4個(gè)子頁(yè)面放在了里面,全局有一個(gè) _currentIndex ,當(dāng) onTap 回調(diào)后后,更新 _currentIndex 的值,執(zhí)行 setState () 后, body 對(duì)應(yīng)的 widget 頁(yè)面發(fā)生改變。而問(wèn)題也就出在這里,當(dāng) body 部分發(fā)生改變時(shí),根據(jù)Flutter的底層渲染邏輯,這里會(huì)移除掉之前的 Widget ,并重新創(chuàng)建新的 Widget ,我們之前在 _viewControllers 放的子頁(yè)面,并不像iOS下是一個(gè)實(shí)例對(duì)象,存在就直接拿來(lái)使用。在Flutter 中 setState () 后界面會(huì)被重新繪制,而 body 部分只知道我要渲染一個(gè)什么樣的 widget ,而該類型的 widget 每次都是會(huì)重新創(chuàng)建,這也就意味著我們?cè)赥ab切換時(shí),每次都是重新創(chuàng)建,所以每次都執(zhí)行了 initState() 。
顯然我們現(xiàn)在的方式是不合理的,那在Flutter中如何管理這樣的子頁(yè)面,而避免重復(fù)渲染吶?
這就要用到一個(gè)新的部件了: PageView() ,內(nèi)部的2個(gè)關(guān)鍵屬性:
子頁(yè)面切換通過(guò) _controller.jumpToPage(index); 來(lái)實(shí)現(xiàn)。
這樣子頁(yè)面也就不會(huì)重新創(chuàng)建渲染了,我們的狀態(tài)保存也就能正常實(shí)現(xiàn)了。
學(xué)習(xí)是一個(gè)循序漸進(jìn)的過(guò)程,我們總是在踩坑中不斷的前行,把坑填平了也就意味著我們?cè)谶@個(gè)新的東西面前立了足,就可能進(jìn)行更多為什么的探索了。
當(dāng)前文章:flutter保存動(dòng)畫,flutter 列表動(dòng)畫
URL網(wǎng)址:http://chinadenli.net/article38/dsgopsp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、定制網(wǎng)站、品牌網(wǎng)站建設(shè)、軟件開發(fā)、網(wǎng)站內(nèi)鏈、品牌網(wǎng)站設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容