Flutter是谷歌的移動UI框架,能夠快速在iOS和Android上構建高質量的原生用戶界面。 Flutter能夠與現有的代碼一塊兒工做。在全世界,Flutter正在被愈來愈多的開發者和組織使用,而且Flutter是徹底免費、開源的。面試
快速開發(毫秒級熱重載)編程
Flutter是一個使用Dart語言開發的跨平臺移動UI框架,經過自建繪製引擎,能高性能、高保真地進行移動開發。Dart囊括了多數編程語言的優勢,它更符合Flutter構建界面的方式。c#
dart是引用傳遞的。併發
Widget會被inflate(填充)到Element,並由Element管理底層渲染樹。Widget並不會直接管理狀態及渲染,而是經過State這個對象來管理狀態。Flutter建立Element的可見樹,相對於Widget來講,是可變的,一般界面開發中,咱們不用直接操做Element,而是由框架層實現內部邏輯。就如一個UI視圖樹中,可能包含有多個TextWidget(Widget被使用屢次),可是放在內部視圖樹的視角,這些TextWidget都是填充到一個個獨立的Element中。Element會持有renderObject和widget的實例。記住,Widget 只是一個配置,RenderObject 負責管理佈局、繪製等操做。框架
在第一次建立 Widget 的時候,會對應建立一個 Element, 而後將該元素插入樹中。若是以後 Widget 發生了變化,則將其與舊的 Widget 進行比較,而且相應地更新 Element。重要的是,Element 不會被重建,只是更新而已。less
繼承(關鍵字 extends)、混入 mixins (關鍵字 with)、接口實現(關鍵字 implements)。這三者能夠同時存在,先後順序是extends -> mixins -> implements。異步
Flutter中的繼承是單繼承,子類重寫超類的方法要用@Override,子類調用超類的方法要用super。async
在Flutter中,Mixins是一種在多個類層次結構中複用類代碼的方法。mixins的對象是類,mixins毫不是繼承,也不是接口,而是一種全新的特性,能夠mixins多個類,mixins的使用須要知足必定條件。編程語言
由於mixins使用的條件,隨着Dart版本一直在變,這裏講的是Dart2.1中使用mixins的條件:ide
mixins類只能繼承自object
mixins類不能有構造函數
一個類能夠mixins多個mixins類
能夠mixins多個類,不破壞Flutter的單繼承
on關鍵字可用於指定異常類型。 on只能用於被mixins標記的類,例如mixins X on A,意思是要mixins X的話,得先接口實現或者繼承A。這裏A能夠是類,也能夠是接口,可是在mixins的時候用法有區別.
on 一個類:
class A { void a(){ print("a"); } } mixin X on A{ void x(){ print("x"); } } class mixinsX extends A with X{ }
on 的是一個接口: 得首先實現這個接口,而後再用mix
class A { void a(){ print("a"); } } mixin X on A{ void x(){ print("x"); } } class implA implements A{ @override void a() {} } class mixinsX2 extends implA with X{ }
普通代碼都是同步執行的,結束後會開始檢查microtask中是否有任務,如有則執行,執行完繼續檢查microtask,直到microtask列隊爲空。最後會去執行event隊列(future)。
future是異步編程,調用自己當即返回,並在稍後的某個時候執行完成時再得到返回結果。在普通代碼中可使用await 等待一個異步調用結束。
isolate是併發編程,Dartm有併發時的共享狀態,全部Dart代碼都在isolate中運行,包括最初的main()。每一個isolate都有它本身的堆內存,意味着其中全部內存數據,包括全局數據,都僅對該isolate可見,它們之間的通訊只能經過傳遞消息的機制完成,消息則經過端口(port)收發。isolate只是一個概念,具體取決於如何實現,好比在Dart VM中一個isolate可能會是一個線程,在Web中可能會是一個Web Worker。
Stream 和 Future 是 Dart 異步處理的核心 API。Future 表示稍後得到的一個數據,全部異步的操做的返回值都用 Future 來表示。可是 Future 只能表示一次異步得到的數據。而 Stream 表示屢次異步得到的數據。好比界面上的按鈕可能會被用戶點擊屢次,因此按鈕上的點擊事件(onClick)就是一個 Stream 。簡單地說,Future將返回一個值,而Stream將返回屢次值。Dart 中統一使用 Stream 處理異步事件流。Stream 和通常的集合相似,都是一組數據,只不過一個是異步推送,一個是同步拉取。
Stream有兩種訂閱模式:單訂閱(single) 和 多訂閱(broadcast)。單訂閱就是隻能有一個訂閱者,而廣播是能夠有多個訂閱者。這就有點相似於消息服務(Message Service)的處理模式。單訂閱相似於點對點,在訂閱者出現以前會持有數據,在訂閱者出現以後就才轉交給它。而廣播相似於發佈訂閱模式,能夠同時有多個訂閱者,當有數據時就會傳遞給全部的訂閱者,而無論當前是否已有訂閱者存在。
Stream 默認處於單訂閱模式,因此同一個 stream 上的 listen 和其它大多數方法只能調用一次,調用第二次就會報錯。但 Stream 能夠經過 transform() 方法(返回另外一個 Stream)進行連續調用。經過 Stream.asBroadcastStream() 能夠將一個單訂閱模式的 Stream 轉換成一個多訂閱模式的 Stream,isBroadcast 屬性能夠判斷當前 Stream 所處的模式。
await for是不斷獲取stream流中的數據,而後執行循環體中的操做。它通常用在直到stream何時完成,而且必須等待傳遞完成以後才能使用,否則就會一直阻塞。
Stream<String> stream = new Stream<String>.fromIterable(['不開心', '面試', '沒', '過']); main() async{ print('上午被開水燙了腳'); await for(String s in stream){ print(s); } print('晚上還沒吃飯'); }
Widget: 在Flutter中,幾乎全部東西都是Widget。將一個Widget想象爲一個可視化的組件(或與應用可視化方面交互的組件),當你須要構建與佈局直接或間接相關的任何內容時,你正在使用Widget。
Widget樹: Widget以樹結構進行組織。包含其餘Widget的widget被稱爲父Widget(或widget容器)。包含在父widget中的widget被稱爲子Widget。
Context: 僅僅是已建立的全部Widget樹結構中的某個Widget的位置引用。簡而言之,將context做爲widget樹的一部分,其中context所對應的widget被添加到此樹中。一個context只從屬於一個widget,它和widget同樣是連接在一塊兒的,而且會造成一個context樹。
State: 定義了StatefulWidget實例的行爲,它包含了用於」交互/干預「Widget信息的行爲和佈局。應用於State的任何更改都會強制重建Widget。
這些狀態的引入,主要是爲了解決多個部件之間的交互和部件自身狀態的維護。
StatelessWidget: 一旦建立就不關心任何變化,在下次構建以前都不會改變。它們除了依賴於自身的配置信息(在父節點構建時提供)外再也不依賴於任何其餘信息。好比典型的Text、Row、Column、Container等,都是StatelessWidget。它的生命週期至關簡單:初始化、經過build()渲染。
StatefulWidget: 在生命週期內,該類Widget所持有的數據可能會發生變化,這樣的數據被稱爲State,這些擁有動態內部數據的Widget被稱爲StatefulWidget。好比複選框、Button等。State會與Context相關聯,而且此關聯是永久性的,State對象將永遠不會改變其Context,即便能夠在樹結構周圍移動,也仍將與該context相關聯。當state與context關聯時,state被視爲已掛載。StatefulWidget由兩部分組成,在初始化時必需要在createState()時初始化一個與之相關的State對象。
initState() : 一旦State對象被建立,initState方法是第一個(構造函數以後)被調用的方法。可經過重寫來執行額外的初始化,如初始化動畫、控制器等。重寫該方法時,應該首先調用super.initState()。在initState中,沒法真正使用context,由於框架尚未徹底將其與state關聯。initState在該State對象的生命週期內將不會再次調用。
didChangeDependencies(): 這是第二個被調用的方法。在這一階段,context已經可用。若是你的Widget連接到了一個InheritedWidget而且/或者你須要初始化一些listeners(基於context),一般會重寫該方法。
build(BuildContext context): 此方法在didChangeDependencies()、didUpdateWidget()以後被調用。每次State對象更新(或當InheritedWidget有新的通知時)都會調用該方法!咱們通常都在build中來編寫真正的功能代碼。爲了強制重建,能夠在須要的時候調用setState((){...})方法。
dispose(): 此方法在Widget被廢棄時調用。可重寫該方法來執行一些清理操做(如解除listeners),並在此以後當即調用super.dispose()。
在flutter中,每一個widget都是被惟一標識的。這個惟一標識在build或rendering階段由框架定義。該標識對應於可選的Key參數,若是省略,Flutter將會自動生成一個。
在flutter中,主要有4種類型的Key:GlobalKey(確保生成的Key在整個應用中惟一,是很昂貴的,容許element在樹周圍移動或變動父節點而不會丟失狀態)、LocalKey、UniqueKey、ObjectKey。
Navigator是在Flutter中負責管理維護頁面堆棧的導航器。MaterialApp在須要的時候,會自動爲咱們建立Navigator。Navigator.of(context),會使用context來向上遍歷Element樹,找到MaterialApp提供的_NavigatorState再調用其push/pop方法完成導航操做。