hello world例子
主要從事網(wǎng)頁設(shè)計、PC網(wǎng)站建設(shè)(電腦版網(wǎng)站建設(shè))、wap網(wǎng)站建設(shè)(手機(jī)版網(wǎng)站建設(shè))、響應(yīng)式網(wǎng)站建設(shè)、程序開發(fā)、微網(wǎng)站、小程序開發(fā)等,憑借多年來在互聯(lián)網(wǎng)的打拼,我們在互聯(lián)網(wǎng)網(wǎng)站建設(shè)行業(yè)積累了豐富的成都網(wǎng)站設(shè)計、成都做網(wǎng)站、網(wǎng)絡(luò)營銷經(jīng)驗(yàn),集策劃、開發(fā)、設(shè)計、營銷、管理等多方位專業(yè)化運(yùn)作于一體,具備承接不同規(guī)模與類型的建設(shè)項目的能力。
在終端打印字符串‘Hello World!’
計算斐波那契數(shù)列
一個簡單的類
計算兩點(diǎn)距離
異步并發(fā)示例
使用了Isolate
1.面向?qū)ο?/p>
對于面向?qū)ο筮@個概念,相信了解Java的同學(xué)對這個概念一定不會陌生。
例如:我們有個Person Object他有很多特征和行為。
這些都是這個Person Object的屬性。
也就是因?yàn)橛辛诉@些特征,行為等等才決定了這個人是誰。
那么回到Dart當(dāng)中,所有的都是對象,那么在就可以可以跟進(jìn)對象的屬性的特征,方法等等來進(jìn)行編程。
之所以我們在這里又特別強(qiáng)調(diào)了一下面向?qū)ο蟮母拍?,是因?yàn)檫@個概念在Dart語言當(dāng)中,至關(guān)重要!
2.最重要的幾個概念
3.Dart的部分特性
4.Dart的內(nèi)置庫
包名
描述
dart:asynv
異步編程,提供Future,Stream類
dart:collection
集合
dart:convert
不同類型的字符編碼解碼
dart:core
Dart語言核心功能,內(nèi)置類型
dart:html
網(wǎng)頁開發(fā)用到的庫
dart:io
文件讀寫,IO相關(guān)
dart:math
數(shù)字常量以及函數(shù),隨機(jī)算法等
dart:svg
事件和動畫矢量圖支持
綜上述所說要想學(xué)Flutter,先學(xué)Dart!關(guān)于Flutter下篇我會講到。為什么離不開dart!
有關(guān)更多面經(jīng)、核心技術(shù)筆記;自己也是從事Android開發(fā)5年有余了;整理了一些Android開發(fā)技術(shù)核心筆記和面經(jīng)題綱, 如有需要的同學(xué)請私信我回復(fù)“核心筆記”或“面試”領(lǐng)?。?/p>
APP 啟動頁在國內(nèi)是最常見也是必備的場景,其中啟動頁在 iOS 上算是強(qiáng)制性的要求,其實(shí)配置啟動頁挺簡單,因?yàn)樵?Flutter 里現(xiàn)在只需要:
一般只要配置無誤并且圖片尺寸匹配,基本上就不會有什么問題, 那既然這樣,還有什么需要適配的呢?
事實(shí)上大部分時候 iOS 是不會有什么問題, 因?yàn)? LaunchScreen.storyboard 的流程本就是 iOS 官方用來做應(yīng)用啟動的過渡;而對于 Andorid 而言,直到 12 之前 windowBackground 這種其實(shí)只能算“民間”野路子 ,所以對于 Andorid 來說,這其中就涉及到一個點(diǎn):
所以下面主要介紹 Flutter 在 Android 上為了這個啟動圖做了哪些騷操作~
在已經(jīng)忘記版本的“遠(yuǎn)古時期” , FlutterActivity 還在 io.flutter.app.FlutterActivity 路徑下的時候,那時啟動頁的邏輯相對簡單,主要是通過 App 的 AndroidManifest 文件里是否配置了 SplashScreenUntilFirstFrame 來進(jìn)行判斷。
在 FlutterActivity 內(nèi)部 FlutterView 被創(chuàng)建的時候,會通過讀取 meta-data 來判斷是否需要使用 createLaunchView 邏輯 :
是不是很簡單,那就會有人疑問為什么要這樣做?我直接配置 Activity 的 android:windowBackground 不就完成了嗎?
這就是上面提到的時間差問題, 因?yàn)閱禹摰?Flutter 渲染完第一幀畫面中間,會出現(xiàn)概率出現(xiàn)黑屏的情況,所以才需要這個行為來實(shí)現(xiàn)過渡 。
經(jīng)歷了“遠(yuǎn)古時代”之后, FlutterActivity 來到了 io.flutter.embedding.android.FlutterActivity , 在到 2.5 版本發(fā)布之前,F(xiàn)lutter 又針對這個啟動過程做了不少調(diào)整和優(yōu)化,其中主要就是 SplashScreen 。
自從開始進(jìn)入 embedding 階段后, FlutterActivity 主要用于實(shí)現(xiàn)了一個叫 Host 的 interface ,其中和我們有關(guān)系的就是 provideSplashScreen 。
默認(rèn)情況下它會從 AndroidManifest 文件里是否配置了 SplashScreenDrawable 來進(jìn)行判斷 。
默認(rèn)情況下當(dāng) AndroidManifest 文件里配置了 SplashScreenDrawable ,那么這個 Drawable 就會在 FlutterActivity 創(chuàng)建 FlutterView 時被構(gòu)建成 DrawableSplashScreen 。
DrawableSplashScreen 其實(shí)就是一個實(shí)現(xiàn)了 io.flutter.embedding.android.SplashScreen 接口的類,它的作用就是:
之后 FlutterActivity 內(nèi)會創(chuàng)建出 FlutterSplashView ,它是個 FrameLayout。
FlutterSplashView 將 FlutterView 和 ImageView 添加到一起, 然后通過 transitionToFlutter 的方法來執(zhí)行動畫,最后動畫結(jié)束時通過 onTransitionComplete 移除 splashScreenView 。
所以整體邏輯就是:
當(dāng)然這里也是分狀態(tài):
當(dāng)然這個階段的 FlutterActivity 也可以通過 override provideSplashScreen 方法來自定義 SplashScreen 。
看到?jīng)]有,做了這么多其實(shí)也就是為了彌補(bǔ)啟動頁和 Flutter 渲染之間, 另外還有一個優(yōu)化,叫 NormalTheme 。
通過該配置 NormalTheme ,在 Activity 啟動時,就會首先執(zhí)行 switchLaunchThemeForNormalTheme(); 方法將主題從 LaunchTheme 切換到 NormalTheme 。
大概配置完就是如下樣子, 前面分析那么多其實(shí)就是為了告訴你,如果出現(xiàn)問題了,你可以從哪個地方去找到對應(yīng)的點(diǎn) 。
講了那么多, Flutter 2.5 之后 provideSplashScreen 和 io.flutter.embedding.android.SplashScreenDrawable 就被棄用了,驚不喜驚喜,意不意外,開不開心 ?
通過源碼你會發(fā)現(xiàn),當(dāng)你設(shè)置了 splashScreen 的時候,會看到一個 log 警告:
為什么會棄用?
其實(shí)這個提議是在 這個 issue 上,然后通過 這個 pr 完成調(diào)整。
大概意思就是: 原本的設(shè)計搞復(fù)雜了,用 OnPreDrawListener 更精準(zhǔn),而且不需要為了后面 Andorid12 的啟動支持做其他兼容,只需要給 FlutterActivity 等類增加接口開關(guān)即可 。
也就是2.5之后 Flutter 使用 ViewTreeObserver.OnPreDrawListener 來實(shí)現(xiàn)延遲直到加載出 Flutter 的第一幀。
為什么說默認(rèn)情況? 因?yàn)檫@個行為在 FlutterActivity 里,是在 getRenderMode() == RenderMode.surface 才會被調(diào)用,而 RenderMode 又和 BackgroundMode 有關(guān)心 。
所以在 2.5 版本后, FlutterActivity 內(nèi)部創(chuàng)建完 FlutterView 后就會執(zhí)行一個 delayFirstAndroidViewDraw 的操作。
這里主要注意一個參數(shù): isFlutterUiDisplayed 。
當(dāng) Flutter 被完成展示的時候, isFlutterUiDisplayed 就會被設(shè)置為 true。
所以當(dāng) Flutter 沒有執(zhí)行完成之前, FlutterView 的 onPreDraw 就會一直返回 false ,這也是 Flutter 2.5 開始之后適配啟動頁的新調(diào)整。
看了這么多,大概可以看到其實(shí)開源項目的推進(jìn)并不是一帆風(fēng)順的,沒有什么是一開始就是最優(yōu)解,而是經(jīng)過多方嘗試和交流,才有了現(xiàn)在的版本,事實(shí)上開源項目里,類似這樣的經(jīng)歷數(shù)不勝數(shù):
當(dāng)我們想創(chuàng)建一個自定義的隱式動畫時,我們可以使用TweenAnimationBuilder.
中文說明
假設(shè)你想創(chuàng)建一個基礎(chǔ)的動畫,這個動畫不會永遠(yuǎn)重復(fù)。它僅僅是一個組件或則一個組件樹。Flutter有一個慣例,將其隱式動畫小部件命名為AnimatedFoo。
tween 設(shè)置動畫的值。開始xxx 結(jié)束xxx
builder: 第一個參數(shù)是BuildContext,第二個是value取決于你要設(shè)置的動畫數(shù)據(jù)。第三個參數(shù)子組件,用于優(yōu)化.
同時還可以設(shè)置運(yùn)動曲線 curve。
onEnd監(jiān)聽,可以在動畫完成時,進(jìn)行下一步動作
設(shè)置子Widget參數(shù)時潛在性能的優(yōu)化。意思是說
builder中的child可以提前構(gòu)建。以參數(shù)的方式傳遞盡力啊。flutter會自動唯一的小部件是什么,它將會需要逐幀重建新的內(nèi)容。而不是其實(shí)圖像的本身。(如果時小的組件,沒啥必要,但是如果是巨大的動畫。作用應(yīng)該會很明顯)
1.動畫原理:在一段時間內(nèi)快速的多次改變UI外觀,由于人眼會產(chǎn)生視覺暫留所以最終看到的就是一個連續(xù)的動畫。
UI的一次改變稱為一個動畫幀,對應(yīng)一次屏幕刷新。
FPS:幀率,每秒的動畫幀數(shù)。
flutter動畫分為兩類:
常見動畫模式:
是一個抽象類,主要的功能是保存動畫的值和狀態(tài)。常用的一個Animation類是Animation double ,是一個在一段時間內(nèi)依次生成一個區(qū)間之間的值的類,可以是線性或者曲線或者其他。
可以生成除double之外的其他類型值,如:Animation Color 或 Animation Size 。
是一個動畫控制器,控制動畫的播放狀態(tài),在屏幕刷新的每一幀,就會生成一個新的值。
包含動畫的啟動forward()、停止stop() 、反向播放 reverse()等方法,在給定的時間段內(nèi)線性的生成從0.0到1.0(默認(rèn)區(qū)間)的數(shù)字。
curve:描述動畫的曲線過程。
curvedAnimation:指定動畫的曲線。
常用Curve:
繼承自Animatable T ,表示的就是一個 Animation 對象的取值范圍,只需要設(shè)置開始和結(jié)束的邊界值(值也支持泛型)。 它唯一的工作就是定義輸入范圍到輸出范圍的映射。
例如,Tween可能會生成從紅到藍(lán)之間的色值,或者從0到255。
Tween.animate:返回一個Animation。
映射過程:
1). Tween.animation通過傳入 aniamtionController 獲得一個_AnimatedEvaluation 類型的 animation 對象(基類為 Animation), 并且將 aniamtionController 和 Tween 對象傳入了 _AnimatedEvaluation 對象。
2). animation.value方法即是調(diào)用 _evaluatable.evaluate(parent)方法, 而 _evaluatable 和 parent 分別為 Tween 對象和 AnimationController 對象。
3). 這里的 animation 其實(shí)就是前面的 AnimationController 對象, transform 方法里面的 animation.value則就是 AnimationController 線性生成的 0.0~1.0 直接的值。 在 lerp 方法里面我們可以看到這個 0.0~1.0 的值被映射到了 begin 和 end 范圍內(nèi)了。
接收一個TickerProvider類型的對象,它的主要職責(zé)是創(chuàng)建Ticker。
防止屏幕外動畫消耗資源。
[圖片上傳失敗...(image-115b94-1636441483468)]
過程:
回調(diào):
不使用addListener()和setState()來給widget添加動畫。
使用AnimatedWidget,將widget分離出來,創(chuàng)建一個可重用動畫的widget,AnimatedWidget中會自動調(diào)用addListener()和setState()
AnimatedModalBarrier、DecoratedBoxTransition、FadeTransition、PositionedTransition、RelativePositionedTransition、RotationTransition、ScaleTransition、SizeTransition、SlideTransition
如何渲染過渡,把渲染過程也抽象出來:
AnimatedBuilder的示例包括: BottomSheet、 PopupMenu、ProgressIndicator、RefreshIndicator、Scaffold、SnackBar、TabBar。
MaterialPageRoute:平臺風(fēng)格一致的路由切換動畫
CupertinoPageRoute:左右切換風(fēng)格
自定義:PageRouteBuilder
1.要創(chuàng)建交織動畫,需要使用多個動畫對象(Animation)。
2.一個AnimationController控制所有的動畫對象。
3.給每一個動畫對象指定時間間隔(Interval)
可以同時對其新、舊子元素添加顯示、隱藏動畫.
當(dāng)AnimatedSwitcher的child發(fā)生變化時(類型或Key不同),舊child會執(zhí)行隱藏動畫,新child會執(zhí)行執(zhí)行顯示動畫。
希望大家支持一下,感謝
使用Tween動畫,改變控件距左距離
展開時,展示菜單控件,動畫正向執(zhí)行;收起后,動畫反向執(zhí)行,隱藏菜單控件;
透明視頻動畫是目前比較流行的實(shí)現(xiàn)動畫的一種, 大廠也相繼開源自己的框架,最終我們選中 騰訊vap ,它支持了Android、IOS、Web,為我們封裝flutter_vap提供了天然的便利,并且它提供了將幀圖片生成帶alpha通道視頻的工具,這簡直太贊了。
VAP(Video Animation Player)是企鵝電競開發(fā),用于播放酷炫動畫的實(shí)現(xiàn)方案。
video for youtube
video for qiniu
apk download
github