在上一篇咱們搭建flutter環境以後,而且建立了一個HelloFlutter咱們的第一個demo,接下來讓咱們看一看flutter的工程目錄以及建立項目運行代碼的部分解析。java
首先工程目錄以下:ios
主要分爲四個部分,第一個部分是Android,第二個部分是iOS,第三個部分是相似build.gradle的配置文件pubspec.yaml,第四個部分是lib文件夾,裏面存放咱們編寫的基於dart語言的源代碼,前兩個部分不會涉及到,咱們主要是寫dart來實現跨平臺。api
那咱們接下來看一下lib下面有一個main.dart的文件,打開以後以下:app
首先看less
void main() => runApp(MyApp());
這是程序的入口函數,進來首先會調用runApp方法,這裏用到了=>箭頭函數和以下格式相似:ide
main(){ return new MyApp(); }
Dart中的箭頭函數,跟kotlin很像。函數
其實=> runApp(MyApp()); 等同於gradle
{
return new MyApp();ui
}spa
那說到這裏就要說一下dart的匿名函數和=>箭頭函數是怎麼聲明的,說白了匿名的含義就是沒有名字的函數,格式以下:
([[Type] param1[, …]]) { codeBlock; };
其實上面若是用箭頭函數來表示,以下:
([[Type] param1[, …]]) => codeBlock;
因此{codeBlock}等同於 =>codeBlock,舉個例子:
var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); });
箭頭函數以下:
list.forEach((item) => print('${list.indexOf(item)}: $item'));
上面的示例定義了一個具備無類型參數的匿名函數item,該函數被list中的每一個item調用,輸出一個字符串,該字符串包含指定索引處的值。
接着說main函數返回一個widget,MyApp就是咱們要展現的啓動界面。
這裏的MyApp類中返回了一個MaterialApp widget,MaterialApp能夠理解爲ui的風格,Android上就是這種風格的UI. ios上咱們可使用CupertinoApp。這個能夠本身修改嘗試在MaterialApp中咱們能夠配置主題顏色,控件的樣式等等。
這裏至關於Android中的Application類, StatelessWidget表示無狀態控件。
MaterialApp代表app的風格是Material Design風格的,這裏咱們能夠配置app的主題相關屬性好比顏色,
按鈕風格等等,相似於Android中的style文件。
主題相關配置,這裏咱們能夠配合app總體的主題樣式,好比總體顏色,控件默認的樣式等。
這個地方就相似於Android中的style文件配置,主要就是主題的配置。
home指定了啓動後顯示的頁面,相似於咱們在AndroidManifest中配置啓動頁面,也就是Android裏面的MainActivity。
接下來咱們看一下MyHomePage這個類
StatefulWidget是一個有狀態的控件,若是你的頁面須要更新ui,那麼該頁面就要繼承自StatefulWidget,因此這個類基本上是必需要繼承的,
跟Android咱們要繼承activity的意義差很少,若是隻是一個純展現的頁面,只須要繼承自StatelessWidget便可,也就是一些靜態頁面
MyHomePage在上面已經被指定爲啓動頁面,該頁面有一個計數的邏輯,會更新ui,因此須要繼承自StatefulWidget。
這裏咱們看一下它的構造函數的格式跟Java不同吧,這是dart語言特有的可選參數,舉個例子:
//◦可選的命名參數, 定義函數時,使用{param1, param2, …},用於指定命名參數。例如 //設置[bold]和[hidden]標誌 void enableFlags({bool bold, bool hidden}) { // ... print(bold.toString()+"、"+hidden.toString()); } //這裏能夠隨便改變傳入參數的順序 enableFlags(bold: true, hidden: false);
咱們能夠隨意更改傳參的順序。
還有一種可選的位置參數,舉個例子:、
//◦可選的位置參數,用[]它們標記爲可選的位置參數: String say(String from, String msg, [String device]) { var result = '$from says $msg'; if (device != null) { result = '$result with a $device'; } print(result); return result; } //能夠傳也能夠不傳,至關於Java重載 say('Bob', 'Howdy'); //結果是: Bob says Howdy say('Bob', 'Howdy', 'smoke signal'); //結果是:Bob says Howdy with a smoke signal
這裏就看到了,咱們能夠傳也能夠不傳,我的感受跟Java的 重載相似。
接着說,全部繼承自StatefulWidget的控件都要重寫createState()這個方法,能夠理解爲指定該頁面的狀態是由誰來控制的,
在Dart中下劃線開頭聲明的變量和方法,其默認訪問權限就是私有的, 相似於java中用private關鍵字修飾,只能在類的內部訪問。
這裏咱們須要指出的是咱們須要_MyHomePageState這個類的對象來控制這個界面,因此咱們重寫createState()這個方法,而且返回了_MyHomePageState對象,而且你們有注意到麼,這裏用到了箭頭函數,咱們以前說的,因此這裏若是不用箭頭函數的話能夠以下代替:
@override _MyHomePageState createState() { return _MyHomePageState(); }
看到這裏是否是以爲這不就是Java的方法重寫而且return麼,其實箭頭函數後面指向的就是咱們要rerun的代碼。
State是一個狀態對象,<>裏面是表示該狀態是跟誰綁定的,咱們修改狀態時就是在該類中進行編寫。
咱們主要看一下build方法:
Scaffold能夠看做是Material Design中的一個模板,看源碼發現它繼承自StatefulWidget,包含了appBar,body,drawer等控件。
appBar 至關於Android中的ToolBar。
其實看起來就是return一個Scaffold對象,這個對象的實例化須要咱們傳入一些參數,傳參數的格式跟Java不同而已,咱們須要傳遞appBar、body、floatingActionButton這個浮動按鈕,而後每一個參數也是個對象,咱們看代碼很容易看到好比appBar須要傳遞title這個參數便可,這個title也是一個對象Text,它也須要一個參數widget.title,這裏的widget實際上就是MyHomePage。
建議初學flutter的同窗仍是不要急着先弄工程,先把dart語言的基本api的使用弄清楚了,再來敲代碼就會快不少了。