flutter現在是越來越火了,現在作為一個iOS開發,如果你不會flutter都好像不算個正常人似的?而且現在的flutter情況,有點像2012年那會兒剛剛興起的iOS,Android開發一樣,會點皮毛UI就可以提升不少身價...這些年過來,有無數的前端跨平臺框架興起。卻只有flutter一家獨秀,說明它還是有兩把刷子的。今天這篇文章內容是基於Mac和Android Studio基礎來開發flutter的,如果你還沒有配置好開發環境,可以在網上搜尋,或者直接到官網安裝。這篇文章主要用來記錄我學習flutter的過程,如果你也對flutter感興趣可以跟著一起練習。
配置好Flutter環境之後,開始建立我們的第一個Flutter工程
建立第一個Flutter工程
開啟iTerm2,cd到~/AndroidStudioProjects目錄,輸入以下命令,沒有iTerms的使用Mac系統自帶的Terminal也行。
flutter create flutter_demo
這裡需要注意,AndroidStudio專案名稱不能使用大寫字母,這裡推薦使用小寫字母加下劃線給工程命名。
開啟對應的目錄,可以看到新建了一個flutter_demo
目錄
接下來,cd到flutter_demo
目錄,在終端輸入flutter run
命令,它就會執行專案,如果你電腦連線了真機,就會自動執行到真機上,沒有真機會去尋找模擬器並執行,模擬器也沒有,就會開啟一個Chrome網頁執行專案(flutter專案目前可以執行在iOS,Android,web上)。我這裡連上了iPhone真機,執行專案會報一個BUILD FAILED的錯誤:
原因是flutter_demo專案生成的iOS專案預設的bundle identifier我們們用不了,去iOS專案裡面修改一下就好了
這裡注意我們免費的開發者證書,在iPhone上最多安裝3個開發中的APP,多了就安裝不了,刪掉之前的APP就好了,再次執行flutter run
可以看到這裡給出了flutter執行的一些關鍵命令,Hot reload熱過載,這個特性對我們開發UI時還是比原生的體驗好不少的,它不用我們重新執行專案就能看到UI的一些改變。Hot restart熱重啟,意思不用退出APP,就直接重新執行了。此時真機上就開啟了我們的第一個flutter工程的APP
HelloFlutter
上面是通過命令建立一個flutter專案,當然在實際開發過程我,我們一般不會這麼操作。使用Android Studio來建立flutter專案。沒有這個選項的同學,在Android Studio的外掛裡面選擇flutter並安裝就有了,如果提示還需要安裝Dart就一塊安裝了,flutter使用的是Dart語言。iOS開發者沒必要被這個新語言給嚇到了,現代的語言基本都差不了太多,敲著敲著就熟悉了 點選後會出現以下介面,目前我們選擇Flutter App就好了 下一個介面會讓我們設定工程名稱,工程位置,工程描述,工程組織,Android語言,iOS語言等等...我這裡設定工程名稱為hello_flutter,其他的預設選擇就好了...也可以根據你自己的需要選擇 點選Finish之後就可以看到完整的工程目錄了,flutter工程的主入口,跟我們iOS專案一樣有一個main.m檔案,flutter的是main.dart檔案,可以看到這個檔案裡面已經有不少初始的程式碼了,今天是我們第一次接觸flutter專案,就不要這裡的程式碼,全部刪掉,我們從第一行程式碼開始自己敲出來
- 匯入material.dart標頭檔案(相當於iOS中UIKit)
- 寫一個main()函式作為主入口
- 呼叫runAPP()函式
- Center類是用來佈局的類,表示一個位置,child屬性表示他有的子控制元件的意思。Text類就是我們文字類,有點兒我們iOS的UILabel的意思,Text類的第一個引數就是具體的文字,省略了引數名,第二個引數
textDirection
表示文字顯示方向,我們習慣的從左至右就是TextDirection.ltr
,left to right。像一些阿拉伯語言,希伯來語的文字就是從右到左顯示的,我這裡試了一下hello world的方向並沒有變化,可能還需要其他設定吧...
執行之後iPhone顯示如下:
自定義Widget
flutter裡面的Widget類叫作小部件,是flutter裡面經常用到的,它分為有狀態的Stateful和Stateless無狀態的。其中無狀態的比較簡單,我們先自定義一個類CustomWidget繼承自StatelessWidget。我們自定義的Widget想要顯示到螢幕上需要實現一個build的函式,系統會呼叫這個函式來渲染我們想要顯示到螢幕上的內容 這個時候,如何將我們的hello flutter顯示到螢幕呢,可以看到runApp函式裡面有一個Center類,我們CustomWidget類的build方法也是返回的一個Center類,所以可以直接將我們CustomWidget初始化給runApp作引數 有些時候,我們發現hot reload無法更新介面,可以使用hot restart,如果hot restart還是無法更新介面,那就需要重新執行一下就可以了。此時我們發現main()函式裡面就只有一句呼叫runApp()程式碼,在Dart語言中,函式定義如果只有一句程式碼,那麼可以省略成如下箭頭形式
設定文字樣式style
按住command再用滑鼠左鍵點選Text類,就會跳到一個text.dart檔案,會看到一個this.style屬性,再次按住command點選,會來到style的宣告部分: 這裡的final表示不可變,常量的意思,類似於Swift裡面的let。可以看到style是一個TextStyle型別,檢視TextStyle類,會發現裡面很多的屬性,比如color,backgroundColor,fontSize,fontWeight...這些都是很熟悉的屬性,接下來我們設定一下hello flutter的一些文字樣式 使用Android Studio快捷鍵command + \檢視介面
Material App
在flutter提供的標頭檔案material.dart中,提供了一個快速構建APP的型別MaterialApp,我們可以使用它來快速構建一個APP的基礎框架。
我們先新建一個App類來寫我們的程式碼
然後我們在App的build方法中,返回一個MaterialApp類,如果MaterialApp不傳入任何引數的話,執行後會發現APP整個螢幕變成紅色,並且顯示了一行文字,意思是出錯了之類的,說明我們的MaterialApp應該是需要傳入一個必要的引數的。
沒錯就像我們iOS的APP同樣需要一個rootViewController一樣,MaterialApp函式需要一個home引數,home引數可以傳一個Widget類,如果傳入我們剛剛寫的CustomWidget類,執行後發現有了一點不一樣的地方
flutter還提供了一個Scaffold的類,這個類翻譯過來叫作腳手架,有點像是我們iOS中的一些基礎控制器(比如UITabBarController,UINavigationController)的封裝。我們來使用一下這個類,這個Scaffold類有一個appBar的屬性,這個屬性就跟我們的UINavigationController的UINavigationBar一樣,appBar是一個AppBar型別,它的title屬性可以傳入一個Widget,我們傳入一個Text類試試看。Scaffold類除了appBar屬性,還有一個body屬性表示的內容,把這個body設定為我們剛剛的CustomWidget,看看是什麼效果,程式碼如下: APP上顯示效果:
MaterialApp還有一個theme的屬性,這個屬性用了配置app的主題,設定一下主題顏色程式碼如下: APP上顯示效果:
初探ListView
在探索ListView之前,我們先把模型實現一下,我們這裡展示的一組關於汽車的圖片和名字,就定義一個Car類,我們新建一個car檔案用來存放我們的模型程式碼,程式碼如下:
再定義一個陣列,用來存放一組汽車模型,我這裡放了一組網路圖片,你可以直接使用,也可以自己在網上找幾張圖片,填入模型陣列中
final List<Car> cars = [
Car(
name: '保時捷918 Spyder',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7d8be6ebc4c7c95b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '蘭博基尼Aventador',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-e3bfd824f30afaac?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '法拉利Enzo',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-a1d64cf5da2d9d99?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: 'Zenvo ST1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-bf883b46690f93ce?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '邁凱倫F1',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-5a7b5550a19b8342?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '薩林S7',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-2e128d18144ad5b8?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '科尼賽克CCR',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-01ced8f6f95219ec?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '布加迪Chiron',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-7fc8359eb61adac0?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '軒尼詩Venom GT',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-d332bf510d61bbc2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
),
Car(
name: '西貝爾Tuatara',
imageUrl:
'https://upload-images.jianshu.io/upload_images/2990730-3dd9a70b25ae6bc9?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240',
)
];
複製程式碼
然後回到main.dart檔案新建一個Home類,用來存放我們ListView相關程式碼,和Xcode一樣Android Studio同樣有程式碼塊功能,直接輸入stl就會出現提示,回車就會生成StatelessWidget類相關程式碼。我們將Scaffold相關的程式碼挪到Home中來。
接下來就是正式開始使用ListView了,ListView跟其他一般的類不太一樣,它的初始化需要呼叫build方法,並且傳入兩個引數,一個是itemCount,一個是itemBuilder,有點類似我們UITableView的cellForRow方法,只不過我們UITableView使用的是代理的設計,而這裡的ListView使用的程式碼塊回撥的設計。
這裡說一個Android Studio的比Xcode好用的地方,如圖的itemCount使用了cars.length但是提示cars報錯,是因為沒有匯入car.dart檔案,給了個小紅燈泡。這個時候,我們游標移動到Car類上,然後使用option + 回車會彈出一個選單,再按一次回車就可以匯入我們的car.dart檔案了
itemBuilder屬性就是一個程式碼塊,用來配置每個item的樣式,我們可以先統一返回一個Text文字看看效果。 顯示效果就是類似於tableView一樣的一行行的文字
接下來介紹一個類似於UIView的容器類Container,它跟UIView類似,可以設定一些顏色,間距,子控制元件之類的,我們來試一下,將Text改為Container,child屬性就是子控制元件的意思,再給child設定為Text,文字就是cars裡面的name,程式碼如下: 再看一下顯示效果
那麼如果我們現在想要顯示圖片加文字的話應該怎麼做呢?這裡再介紹一個Column類,和前面介紹Center類類似,同樣是屬於佈局的類,Column表示上下的佈局,因為我們想把圖片和文字上下襬放,所以需要用到Column這個類。然後關於圖片的顯示,這裡我們先不講怎麼去網路請求,而是直接使用Image類提供的一個方法去載入網路圖片,程式碼如圖: 顯示效果如圖:
這個時候,你應該也猜到了,如果挪動children裡面Text和Image和順序,會發現圖片和文字的順序就交換了,是不是很容易理解。如果想要調整圖片和文字之間的間距怎麼調呢,使用SizedBox類,傳一個height就可以調整間距了,也可以繼續使用Container,程式碼如下:
如果覺得itemBuilder的程式碼太長,也可以將它的程式碼封裝到一個方法裡面,例如我這裡使用iOS中的_cellForRow來命名這個方法。使用下劃線的意義的是表示這是一個私有方法。
APP右上角會發現有一個debug圖示,這個圖示的顯示在MaterialApp類裡面有一個屬性可以控制顯示隱藏。
debugShowCheckedModeBanner: false
常用Widget介紹
在介紹常用Widget之前,我們想把剛剛寫的ListView相關程式碼,封裝到一個檔案內,這樣方便以後我們回頭學習。listView_demo程式碼如下: 這個時候,main.dart檔案內的Home類的build方法裡,返回我們的ListViewDemo初始化方法就行了。
然後再新建一個新的base_widget檔案,用來存放我們將要介紹的基礎Widget程式碼。 可以在main.dart檔案中直接使用我的BaseWidgetDemo初始化方法,這樣我們就不需要再去main.dart檔案修改程式碼了。每介紹一個新Widget直接修改BaseWidgetDemo的build方法返回值為我們的自定義類xxxDemo()就好了
第一個介紹是Text
Text
Text我們一開始講過了,這裡就再講一點關於字串相關的,如果需要拼接字串可以使用$符號,如果字串中有特殊符號,那就使用${}。其他Text常用的屬性,跟我們iOS中都差不太多,需要注意的是Text的樣式,是在style裡面設定的。下面看一下APP顯示的效果
RichText
RichText就是富文字,它的text屬性可以傳一個TextSpan的類,這個TextSpan類可以設定text文字,設定style樣式,還可以設定children子控制元件,這樣就可以無限加花樣拼接各種字串在一起,程式碼如下 APP上顯示的效果:
Container,Row
Container是個容器,Row是個用於佈局的類,跟Column,Center類似,根據程式碼檢視一下APP的顯示,就能大概明白意思了,程式碼如下: APP顯示如下:
總結
今天介紹了Flutter裡面的許多的基礎Widget,有用於佈局的Center,Row,Column...有用於顯示文字的Text,RichText,TextSpan...有列表展示ListView,有基礎架構Scaffold,MaterialApp類,雖然東西有點多,但基本還沒有什麼難以理解的內容