什么是 Flutter?
Flutter mobile app SDK是一種新的方式來構(gòu)建漂亮的原生移動(dòng)應(yīng)用程序,擺脫過去常見的“千篇一律”的應(yīng)用程序。用過Flutter的人都對它贊賞有加;
相比較其他新型系統(tǒng),人們想知道是什么讓它與眾不同,換句話說,“Flutter的創(chuàng)新和令人興奮的內(nèi)容到底是什么?”,這是個(gè)好問題。本文將從技術(shù)角度回答這個(gè)問題。
首先,先來講點(diǎn)歷史。
移動(dòng)應(yīng)用程序開發(fā)的簡史
移動(dòng)應(yīng)用程序開發(fā)是一個(gè)相對較新的領(lǐng)域。 第三方開發(fā)人員已經(jīng)能夠在不到十年的時(shí)間里構(gòu)建移動(dòng)應(yīng)用程序,所以此類工具仍在不斷發(fā)展的現(xiàn)象并不令人覺得奇怪。
平臺(tái)軟件開發(fā)工具(Platform SDK)
Apple iOS SDK于2008年發(fā)布,Google Android SDK于2009年發(fā)布。這兩個(gè)SDK分別基于不同的語言:Objective-C和Java。
在這個(gè)模型中,你的app通過與平臺(tái)(Platform)通信以創(chuàng)建小部件(Widgets)或訪問相機(jī)等服務(wù)。 窗口小部件會(huì)呈現(xiàn)在屏幕畫布上(Canvas),同時(shí)事件(Event)會(huì)被傳遞到窗口小部件。 雖然這是一個(gè)簡單的架構(gòu),但你幾乎要為每個(gè)平臺(tái)創(chuàng)建單獨(dú)的應(yīng)用程序,因?yàn)樵诓煌脚_(tái)上的小部件也是不同的。這樣的軟件開發(fā)難度可想而知更不用說還要使用原生語言開發(fā)了。
網(wǎng)頁視圖(Web view)
Web View是史上第一個(gè)跨平臺(tái)框架,它基于JavaScript和WebViews,其例子包括一系列相關(guān)框架 :PhoneGap,Apache Cordova,Ionic等。 在Apple發(fā)布iOS SDK之前,Apple建議第三方開發(fā)人員使用Webapp為iPhone編寫程序。因此使用Web技術(shù)構(gòu)建跨平臺(tái)應(yīng)用程序是具有代表性的一步。
在這個(gè)框架中,你的app會(huì)創(chuàng)建HTML并將其顯示在平臺(tái)上的WebView中。 請注意,像JavaScript這樣的語言很難直接與本機(jī)代碼(如服務(wù))對話,因此它們會(huì)經(jīng)歷一個(gè)“橋”,在JavaScript領(lǐng)域和本機(jī)領(lǐng)域之間進(jìn)行上下文切換。 由于平臺(tái)服務(wù)通常不會(huì)經(jīng)常被調(diào)用,因此這不會(huì)導(dǎo)致太多性能問題。
響應(yīng)視圖(Reactive Views)
當(dāng)下,滿大街都是像ReactJS(或是其他)這樣的響應(yīng)式網(wǎng)頁編程框架,主要是因?yàn)樗鼈兘梃b了響應(yīng)式編程的編程模式來簡化Web視圖。2015年,React Native的建立給手機(jī)app上的響應(yīng)式開發(fā)提供了許多便利。
React Native非常受歡迎,但是如果它想從JavaScript域中訪問處于平臺(tái)域(Platform)中的平臺(tái)部件(Widget),它就必須通過橋接器(Bridge)。 通常,小部件需要被頻繁調(diào)用(在動(dòng)畫,轉(zhuǎn)換期間或當(dāng)用戶用手指“刷”屏幕上的某些內(nèi)容時(shí),調(diào)用次數(shù)被限制在了每秒最多60次),這就可能會(huì)導(dǎo)致性能問題。就像one article about React Native所說:
這是理解React Native性能的主要關(guān)鍵之一。 每個(gè)領(lǐng)域本身都非???。 當(dāng)我們從一個(gè)領(lǐng)域轉(zhuǎn)移到另一個(gè)領(lǐng)域時(shí),通常會(huì)出現(xiàn)性能瓶頸。 為了構(gòu)建高性能的React Native應(yīng)用程序,我們必須將橋上的數(shù)據(jù)傳遞保持在一定限度之內(nèi)。
Flutter
與React Native一樣,F(xiàn)lutter也提供了響應(yīng)式視圖。 Flutter采用不同的方法來避免因使用編譯的編程語言(即Dart)而需要JavaScript橋接從而導(dǎo)致的性能問題。Dart是“提前”(AOT)編譯為多個(gè)平臺(tái)的原生代碼。 它能夠與Flutter與平臺(tái)進(jìn)直接行通信,而無需通過執(zhí)行上下文切換的JavaScript橋接器。 此外,編譯為原生代碼的應(yīng)用程序還可以縮短程序的啟動(dòng)時(shí)間。
事實(shí)上,F(xiàn)lutter是唯一的,不需要Javascript橋接的手機(jī)SDK。這足以使得它變得很有趣并值得一試。不僅如此,F(xiàn)lutter還有一些更具革命性的東西,比如它實(shí)現(xiàn)小部件的方式。
Flutter的小部件 (Widget)
窗口小部件是影響和控制應(yīng)用程序視圖和界面的元素。 說小部件是移動(dòng)應(yīng)用程序最重要的部分之一并不夸張。 事實(shí)上,單獨(dú)的一個(gè)小部件就足以創(chuàng)建或破壞一個(gè)應(yīng)用程序。
- 小部件的外觀和感覺是至關(guān)重要的。 小部看起來好看,需要適配各種屏幕尺寸。同時(shí),他們也需要感覺自然。
- 小部件必須快速執(zhí)行: 創(chuàng)建窗口小部件樹,伸縮窗口小部件(實(shí)例化他們的子窗口),將它們放在屏幕上,渲染它們,或(尤其是)為它們設(shè)置動(dòng)畫。
- 對于現(xiàn)代應(yīng)用程序,窗口小部件應(yīng)該是可擴(kuò)展和可自定義的。開發(fā)人員希望能夠添加令人愉快的新窗口小部件,并自定義與應(yīng)用程序的品牌相適應(yīng)的窗口小部件。
Flutter有一個(gè)新的架構(gòu),包括良好的外觀,反應(yīng)速度快,可定制和可擴(kuò)展的小部件。 沒錯(cuò),F(xiàn)lutter不使用平臺(tái)小部件(或DOM WebViews),它提供了自己的小部件。
Flutter將小部件和渲染器放到應(yīng)用程序域中而不是傳統(tǒng)的平臺(tái)域中,這使小部件可以自定義和擴(kuò)展。 Flutter要求平臺(tái)提供畫布(Canvas)(應(yīng)用程序在其中呈現(xiàn)小部件以便它們可以出現(xiàn)在設(shè)備屏幕上)及訪問事件(觸摸,計(jì)時(shí)器等)和服務(wù)(位置,相機(jī)等)。
Dart程序(綠色)和本機(jī)平臺(tái)代碼(藍(lán)色,iOS或Android)之間仍然有一個(gè)接口,可以進(jìn)行數(shù)據(jù)編碼和解碼,但這比JavaScript橋接器快幾個(gè)數(shù)量級(jí)。
事實(shí)上,將小部件和渲染器移動(dòng)到應(yīng)用程序中會(huì)影響應(yīng)用程序的大小。 Android上Flutter應(yīng)用程序的最小大小約為4.7MB,相當(dāng)于使用其他工具構(gòu)建的最小應(yīng)用程序的大小。
本文的其余部分將討論這些好處。
布局(Layout)
在Flutter中最大的提升之一是Layout(布局)。Layout(布局)基于一些規(guī)則(也叫約束)決定了widgets(小部件)的大小和位置。
傳統(tǒng)上,布局使用大量能夠被應(yīng)用到(幾乎)所有小部件的規(guī)則。這些規(guī)則被接入多種布局思路。我們以CSS布局為例,因?yàn)樗苤ūM管 安卓和iOS的布局基本上是相似的)。CSS具有的一些屬性(規(guī)則)可應(yīng)用于HTML元素(小部件)。CSS3定義了375個(gè)屬性。
CSS包含許多布局模型,包括(多個(gè))框模型、浮動(dòng)元素、表、多列文本、分頁媒體等等。后來又添加了其他的布局模型,比如flexbox和grid,因?yàn)殚_發(fā)人員和設(shè)計(jì)師需要對布局進(jìn)行更多的控制,并使用表格和透明圖像來獲得他們想要的東西。在傳統(tǒng)布局中,開發(fā)人員無法添加新的布局模型,因此必須將flexbox和grid添加到CSS中,并在所有瀏覽器上實(shí)現(xiàn)。
傳統(tǒng)布局的另一個(gè)問題是,規(guī)則可以相互交互(甚至沖突),元素通常有許多規(guī)則應(yīng)用于它們。這使得布局變慢。更糟糕的是,布局性能通常是N-的平方階,因此隨著元素?cái)?shù)量的增加,布局會(huì)變得更慢。
Flutter最初是由谷歌的Chrome瀏覽器團(tuán)隊(duì)成員進(jìn)行的一項(xiàng)實(shí)驗(yàn)。我們想看看如果我們忽略傳統(tǒng)的布局模型,是否可以構(gòu)建更快的渲染器。幾周后,我們?nèi)〉昧孙@著的性能提升。我們發(fā)現(xiàn):
- 大多數(shù)布局相對簡單,例如:滾動(dòng)頁面上的文本、大小和位置僅取決于顯示大小的固定矩形,以及一些表格、浮動(dòng)元素等。
- 大多數(shù)布局是小部件子樹的本地布局,該子樹通常使用一個(gè)布局模型,因此這些小部件只需要支持少量規(guī)則。
我們意識(shí)到,如果我們把它反過來看,布局可以大大簡化:
- 每個(gè)小部件將指定自己的簡單布局模型,而不是一大堆可以應(yīng)用于任何小部件的布局規(guī)則。?因?yàn)槊總€(gè)小部件需要考慮的布局規(guī)則要少得多,所以可以對布局進(jìn)行大量優(yōu)化。
- 為了進(jìn)一步簡化布局,我們幾乎把所有東西都變成了一個(gè)小部件。
下面是Flutter代碼,用于創(chuàng)建一個(gè)布局簡單的小部件樹:
new Center(child: new Column(children: [new Text('Hello, World!')),new Icon(Icons.star, color: Colors.green)]))
這段代碼足夠語義化,您可以很容易地想象它將產(chǎn)生什么,但是結(jié)果顯示如下:
在這段代碼中,一切都是一個(gè)小部件,包括布局在內(nèi)。中心(Center)小部件將它的子部件放在其父部件(例如屏幕)中。列布(Column)局小部件垂直地排列其子部件(小部件列表)。該列包含一個(gè)文本(Text)小部件和一個(gè)圖標(biāo)(Icon)小部件(圖標(biāo)小部件具有屬性及其顏色)。
在Flutter中,置于中心和填充的是小部件。主題是小部件,適用于它們的子組件。甚至應(yīng)用程序和導(dǎo)航都是小部件。
Flutter 包含許多用于布局的小部件,不僅包括列,還包括行、網(wǎng)格、列表等。此外,F(xiàn)lutter還有一個(gè)獨(dú)特的布局模型,我們稱之為“sliver layout model”,用于滾動(dòng)。Flutter中的布局非???,可以用來滾動(dòng)頁面。想一下。滾動(dòng)必須是即時(shí)的和平滑的,當(dāng)用戶在物理屏幕上拖動(dòng)屏幕圖像時(shí),用戶感覺屏幕圖像是附著在他們的手指上的。
通過使用布局來滾動(dòng),F(xiàn)lutter可以實(shí)現(xiàn)高級(jí)類型的滾動(dòng),如下所示。注意這些都是GIF動(dòng)畫圖像,F(xiàn)lutter更平滑。你可以(也應(yīng)該)自己運(yùn)行這些應(yīng)用程序;請參閱本文末尾的參考資料部分。
Flutter Gallery appPosse Gallery appPosse Gallery app
在大多數(shù)情況下,F(xiàn)lutter可以一次完成布局,這意味著在線性時(shí)間內(nèi)完成布局,因此它可以處理大量小部件。Flutter還可以進(jìn)行緩存和其他操作,因此它可以在可能的情況下完全避免布局。
自定義設(shè)計(jì)
因?yàn)樾〔考F(xiàn)在是應(yīng)用程序的一部分,所以可以添加新的小部件,并定制現(xiàn)有的小部件,使其具有不同的外觀或感覺,或與公司的品牌相匹配。移動(dòng)設(shè)計(jì)的趨勢已經(jīng)不再是幾年前常見的千篇一律的應(yīng)用程序,而是轉(zhuǎn)向取悅用戶并贏得獎(jiǎng)項(xiàng)的定制設(shè)計(jì)。
Flutter為Android、iOS和材料設(shè)計(jì)提供了豐富的、可定制的小部件集(事實(shí)上,我們聽說Flutter有著最精確的材料設(shè)計(jì))。我們使用Flutter的可定制性來構(gòu)建這些小部件集,以匹配多個(gè)平臺(tái)上本機(jī)小部件的外觀。應(yīng)用程序開發(fā)人員可以使用相同的可定制性來進(jìn)一步調(diào)整小部件以滿足他們的需求。
再談?wù)劷换バ砸晥D
用于響應(yīng)web視圖的庫引入了virtual DOM。DOM是HTML文檔對象模型,是JavaScript用來操作HTML文檔的API,表示為元素樹。virtual DOM是使用編程語言(在本例中是JavaScript)中的對象創(chuàng)建的DOM的抽象版本。
在響應(yīng)式web視圖中(由諸如ReactJS等系統(tǒng)實(shí)現(xiàn)),virtual DOM是不可變的,每次發(fā)生變化都要從頭開始重建。
將virtual DOM與實(shí)際DOM進(jìn)行比較,以生成一組最小的更改,然后執(zhí)行這些更改來更新實(shí)際DOM。
最后,平臺(tái)重新呈現(xiàn)真實(shí)的DOM并將其繪制到畫布中。
這聽起來可能需要大量額外的工作,但這是非常值得的,因?yàn)?a target="_blank">操作HTML DOM非常代價(jià)非常高昂。
React Native也做了類似的事情,不過是針對移動(dòng)應(yīng)用。它在移動(dòng)平臺(tái)上操作本地小部件,而不是DOM。它不是一個(gè)虛擬DOM,而是構(gòu)建一個(gè)小部件的虛擬樹,并將其與本機(jī)小部件進(jìn)行比較,只更新那些已經(jīng)更改的小部件。
請記住,React Native必須通過橋與本機(jī)小部件進(jìn)行通信,因此虛擬小部件樹有助于將橋上的傳遞保持在最低限度,同時(shí)仍然允許使用本機(jī)小部件。最后,一旦本地小部件被更新,平臺(tái)就會(huì)將它們呈現(xiàn)給畫布。
React Native是移動(dòng)開發(fā)的一大勝利,也是Flutter的靈感來源,但Flutter更進(jìn)一步。
回想一下,在Flutter中,小部件和渲染器已經(jīng)從平臺(tái)提升到用戶的應(yīng)用程序中。由于沒有本地平臺(tái)小部件可操作,所以原來的虛擬小部件樹現(xiàn)在變成了小部件樹。Flutter呈現(xiàn)小部件樹并將其繪制到平臺(tái)畫布。這很好,很簡單(而且很快)。此外,動(dòng)畫發(fā)生在用戶空間中,因此應(yīng)用程序(以及開發(fā)人員)對它有更多的控制。
Flutter渲染器本身很有趣:它使用幾個(gè)內(nèi)部樹結(jié)構(gòu)只渲染那些需要在屏幕上更新的小部件。例如,渲染器使用“使用合成的結(jié)構(gòu)重繪”(“結(jié)構(gòu)”的意思是通過小部件,這比通過屏幕上的矩形區(qū)域更有效)。未更改的小部件,即使是那些已經(jīng)移動(dòng)的小部件,也會(huì)從緩存中進(jìn)行“位傳輸(bit blit)”,這非???。這是使?jié)L動(dòng)在抖動(dòng)中表現(xiàn)得如此出色的原因之一,即使是在高級(jí)滾動(dòng)中(如上所述)。
Dart 編程語言
因?yàn)镕lutter與其他使用響應(yīng)視圖的系統(tǒng)一樣, 為每個(gè)新幀刷新視圖樹,它創(chuàng)建了許多僅存活一幀(六十分之一秒)的對象。并且,Dart使用對于這類系統(tǒng)非常有效的“分代垃圾收集技術(shù)”,因?yàn)檫@樣做可以降低回收對象(特別是短命的對象)的消耗。此外,Dart僅使用單個(gè)指針的增減便能完成對象的分配,這種指針運(yùn)作很快并且不需要鎖定。這有助于避免UI丟幀和卡頓。
Dart還有一個(gè)“ tree shaking ”編譯器,它只包含你的應(yīng)用程序所需的代碼。您可以放心地使用大型小部件庫,即使您只會(huì)用到庫中的一個(gè)或兩個(gè)小部件。有關(guān)Dart的更多信息,請閱讀“ 為什么Flutter使用Dart ”。
實(shí)時(shí)重載
Flutter最受歡迎的原因之一就是其快速且有狀態(tài)顯示的實(shí)時(shí)重新加載功能。您可以在一個(gè)Flutter應(yīng)用程序運(yùn)行時(shí)對其進(jìn)行更改,它將重新加載已更改的應(yīng)用程序代碼,并讓它從停止的地方繼續(xù)運(yùn)行,通常在不到一秒鐘的時(shí)間內(nèi)。如果您的應(yīng)用程序遇到錯(cuò)誤,您通??梢孕迯?fù)錯(cuò)誤,然后繼續(xù),就像錯(cuò)誤從未發(fā)生過一樣。即使你必須做一個(gè)完全重新加載,它依舊是很快的。
開發(fā)者們告訴我們這讓他們“畫”出他們自己的應(yīng)用程序,做出一個(gè)改動(dòng)并幾乎實(shí)時(shí)看到結(jié)果卻不用重新啟動(dòng)應(yīng)用程序。
兼容性
因?yàn)樾〔考òㄓ糜谛〔考匿秩酒鳎┦菓?yīng)用程序的一部分,而不是平臺(tái)的一部分,所以無需“適配鏈接庫(Compact libraries)”。 您的應(yīng)用不僅能運(yùn)行,而且能在最近的系統(tǒng)版本上正常運(yùn)行(安卓4.1及IOS 8.0)。這大大減少了在舊操作系統(tǒng)版本上測試應(yīng)用程序的需求。此外,您的應(yīng)用程序很可能適用于未來的操作系統(tǒng)版本。
有一個(gè)潛在的問題是,因?yàn)镕lutter不使用原生平臺(tái)的小部件,所以當(dāng)支持新小部件的新版iOS或安卓發(fā)布時(shí),或是當(dāng)老版本的小部件的外觀和行為方式被改變時(shí),F(xiàn)lutter小部件是否需要很長時(shí)間才能更新?
- 首先,Google是Flutter的一個(gè)重要內(nèi)部用戶,因此我們有足夠的熱情來更新小部件集以使其保持最新狀態(tài)并盡可能接近當(dāng)前新平臺(tái)的小部件。
- 就算窗口小部件遲遲不更新,F(xiàn)lutter的小部件具有很強(qiáng)的可擴(kuò)展和可定制能力,任何人都可以更新它們,即使是你。于是,人們甚至不必提交請求,您也不必等待Flutter本身更新。
- 以上幾點(diǎn)僅適用于當(dāng)您希望在應(yīng)用中使用新的小部件時(shí)。如果您不希望更改影響應(yīng)用的外觀或行為方式,同樣也是可以的。窗口小部件是您應(yīng)用的一部分,因此窗口小部件永遠(yuǎn)不會(huì)在您不知情的情況下更改并使您的應(yīng)用看起來很糟糕(或者更糟糕的是,導(dǎo)致應(yīng)用無法運(yùn)行)。
- 此外,您可以通過自行編寫小部件,以便即使在較舊的OS版本上也可以使用新的小部件。
其他優(yōu)點(diǎn)
Flutter的簡單性使它變得更快,同時(shí)它具有普遍的可定制性和可擴(kuò)展性,使其功能強(qiáng)大。
Dart有一個(gè)軟件包存儲(chǔ)庫,因此您可以擴(kuò)展應(yīng)用程序的功能。例如,有許多軟件包可以輕松訪問Firebase,因此您可以構(gòu)建“無服務(wù)器”應(yīng)用程序。外部貢獻(xiàn)者創(chuàng)建了一個(gè)包,允許您訪問Redux數(shù)據(jù)存儲(chǔ)。還有一些稱為“ plugins(插件)”的軟件包,可以以獨(dú)立于操作系統(tǒng)的方式,更輕松地訪問平臺(tái)服務(wù)和硬件,例如 加速度計(jì)或攝像頭。
當(dāng)然,F(xiàn)lutter也是開源的,再加上Flutter渲染堆棧是你應(yīng)用程序的一部分,這意味著你可以為個(gè)人應(yīng)用程序自定義幾乎任何你想要的東西。此圖中的所有綠色都可以自定義:
所以,F(xiàn)lutter到底新在哪,為何如此吸引人
如果有人像這樣問你,現(xiàn)在你知道該如何回答它們了:
- 響應(yīng)式視圖的優(yōu)點(diǎn),不用JavaScript的橋接
- 快速,流暢,可預(yù)測; 代碼將AOT編譯為本機(jī)(ARM)代碼
- 開發(fā)人員可以完全控制小部件和布局
- 配有漂亮的可定制小部件
- 出色的開發(fā)工具,具有驚人的實(shí)時(shí)重載功能
- 性能更高,兼容性更強(qiáng),更有趣
你注意到我遺漏了什么嗎?其實(shí)那是人們在談?wù)揊lutter時(shí)首先提到的東西,但對我而言,這是Flutter最無趣的事情之一。
事實(shí)上,F(xiàn)lutter可以從單個(gè)代碼庫為多個(gè)平臺(tái)構(gòu)建漂亮而快速的應(yīng)用程序。當(dāng)然,它本身就是為此而生的!它的可定制性和可擴(kuò)展性,可以輕松地將Flutter定位到多個(gè)平臺(tái),而不會(huì)放棄性能或功耗。
革命性
我也從未完全解釋為什么Flutter是“革命性的”。但這樣解釋起來很合適,因?yàn)?a target="_blank">外部開發(fā)人員使用Flutter構(gòu)建的第一個(gè)主要應(yīng)用程序之一是“ 漢密爾頓:美國音樂劇 ” 的官方應(yīng)用程序,它發(fā)生在美國獨(dú)立戰(zhàn)爭時(shí)期。漢密爾頓是有史以來最受歡迎的百老匯音樂劇之一。
項(xiàng)目經(jīng)理Posse表示,他們選擇了Flutter,因?yàn)樗麄冃枰?nbsp;在短短的三個(gè)月內(nèi) ” 構(gòu)建應(yīng)用程序。他們稱之為“為革命性的演出創(chuàng)建革命性的應(yīng)用”,并稱“Flutter是美麗,高性能,品牌驅(qū)動(dòng)的移動(dòng)體驗(yàn)的絕佳選擇。” 他們還在 Google Developer Days會(huì)議上就他們構(gòu)建Flutter的應(yīng)用程序的體驗(yàn)發(fā)表了講話。該應(yīng)用程序可在Android和iOS上使用,并獲得好評(píng)如潮。
一起投身變革吧
2018年12月4日,Flutter 1.0發(fā)布。2021年3月4日,F(xiàn)lutter 2.0 發(fā)布,Google 將繼續(xù)為其添加更多功能,并且計(jì)劃進(jìn)行更多優(yōu)化。Flutter的使用已經(jīng)開始,全球有超過250,000名開發(fā)人員。Flutter目前在Github上活躍的軟件存儲(chǔ)庫中排名前20位。
如果您對Flutter感興趣,可以安裝它并使用安裝附帶的一些示例應(yīng)用程序。一定要查看有狀態(tài)顯示的實(shí)時(shí)重載。
如果您不是開發(fā)人員或只是想看一些應(yīng)用程序,您可以安裝使用Flutter構(gòu)建的應(yīng)用程序,并查看它們的外觀和性能。我推薦Hamilton應(yīng)用程序,但還有其他優(yōu)秀的程序?;蛘吣€可以觀看來自Google I / O的視頻。
資源
- 觀看來自Google I / O 2018的Flutter視頻
- 觀看2018年 1月23日至24日在加利福尼亞州洛杉磯舉行的DartConf 2018的視頻
- 介紹Flutter的視頻。
網(wǎng)站:
- The Flutter website
- The source repositories (pull requests welcome!)
- More helpful links
- Gitter channel
視頻:
- Experience building the Hamilton app, at GDD
- Live coding a Flutter app, at Google I/O
- Live coding with a designer, at Google I/O
- “Flutter, a new hope” at Droidcon Italy
- “The Flutter rendering pipeline”
應(yīng)用:
- The app for Hamilton: An American Musical
- Flutter Gallery: for Android, on Github (also included in the flutter install at examples/flutter_gallery)
- Posse Gallery
- Friendlychat: first codelab, Firebase codelab, on Github