參考官網的的開始使用,配置好開發環境即可進行 Flutter 開發了,當然開發前還是有必要了解一下 Dart 這門語言的,接下來涉及到與其他開發語言不太相同的地方會在文章裡提出來。本教程使用的 flutter 版本為穩定版本 v2.0.6。
建立Flutter 工程
推薦使用命令列的方式新建工程(使用 IDE 建立的過程會比較慢),命令如下:
flutter create hello_world
複製程式碼
Flutter 會預設建立一個示例工程,然後使用命令 開啟工程(code 命令是 vscode 的一個別名,需要在.zshrc配置別名:alias code='/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code'
code hello_word
複製程式碼
專案目錄結構如下圖所示: 各個目錄或檔案說明如下:
- android:安卓原生工程配置相關檔案,包括應用圖示,原生資源,許可權配置等,可以參考之前的關於安卓打包釋出的文章:Flutter 如何釋出安卓應用?
- ios:iOS 原生工程配置相關檔案,熟悉 iOS 開發的會知道具體的用途,其中 最主要的是 Runner 下,設定到原生的配置,如最關鍵的 InfoPlist 檔案,以及許可權相關的配置,這些配置建議在 Xcode 中配置會更為直觀。
- build:打包輸出檔案,主要是安卓打包檔案,iOS 打包需要通過 Xcode 完成。
- lib:最重要的目錄,所有原始碼都在這個目錄,其中 main.dart 是入口檔案,而 main 方法是入口方法。
- test:測試相關檔案
- web:Flutter 2.0引入的,支援三端統一的 web 端檔案
- pubspec.yaml:這個檔案十分重要,所有的第三方依賴,以及檔案依賴都通過這個檔案管理,類似與蘋果的 podfile 和安卓的 gradle 檔案。
執行應用
如果要在安卓模擬器執行,則需要安裝安卓 Studio,並配置好模擬器,至於安卓真機除錯與安卓應用開發類似。蘋果也一樣,需要安裝 Xcode並啟動模擬器。真機除錯蘋果相對比較麻煩,需要有開發者賬號,將真機的 identifier(裝置唯一識別符號)加入到對應應用的開發裝置中,這個可以自行百度搜尋如何配置。
完成配置後,選擇要執行的裝置或模擬器(右下角會顯示當前選定的裝置,如果沒選則是 No Device,如下圖),命令列執行 flutter run
皆可完成編譯和進入程式碼除錯。
Flutter 應用在除錯過程中是支援熱過載的(pub依賴改變了需要重新編譯),因此儘量使用熱過載,畢竟編譯一次時間停長的。
開發裝置配置
如果是要執行模擬器,對開發的裝置要求還是挺高的,推薦使用 Mac Pro(16GB 記憶體)進行開發。Windows 電腦的話至少也需要16GB 記憶體,模擬器一旦執行起來那“呼呼”的風扇聲讓人聽了感覺電腦幹活挺累的!
來點小修改
執行起來 demo 了,不動手改改程式碼過過癮都沒什麼太大感覺,我們來實現在螢幕中間顯示 Logo,點選後切換圖片的簡單修改。
使用圖片資源需要兩個步驟,第一建立一個圖片資料夾存放圖片資源,第二是需要在 pubspec檔案中指定依賴的資源目錄。新建一個 images 資料夾存放圖片檔案,將圖片檔案(avatar.jpg 和qrcode.jpg)放到images 目錄下。在 pubspec.yaml 檔案中設定 assets 屬性:
flutter:
uses-material-design: true
assets:
- images/avatar.jpg
- images/qrcode.jpg
# 其他配置
複製程式碼
注意放置的位置不要弄錯了,在 pubspec.yaml 中有相應的註釋。配置完成後需要執行 flutter pub get
命令更新一下依賴的資源。
主要程式碼如下所示:
class _MyHomePageState extends State<MyHomePage> {
List _imageNames = [
{'image': 'images/avatar.jpg', 'text': '島上碼農'},
{'image': 'images/qrcode.jpg', 'text': '掃碼關注'}
];
int _index = 0;
void _onSiwtch() {
setState(() {
_index = (++_index) % _imageNames.length;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Container(
width: 300,
height: 300,
child: Column(
children: [
Container(
width: 128,
height: 128,
margin: EdgeInsets.only(top: 10, bottom: 10),
child: Image.asset(
_imageNames[_index]['image'],
fit: BoxFit.cover,
),
),
Text(
_imageNames[_index]['text'],
),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _onSiwtch,
tooltip: '切換',
child: Icon(Icons.swap_horizontal_circle_outlined),
),
);
}
}
複製程式碼
程式碼邏輯如下: _MyHomePageState類是 MyHomePage 的 一個有狀態元件,Flutter 的元件和 React 的類似,分為無狀態和有狀態,無狀態元件無法進行資料更新,有狀態元件有自己的資料狀態,根據資料狀態更新介面。
下劃線_代表這個類、方法或成員變數是私有的,在類的外部無法訪問。在_MyHomePageState 中定義了一個 Map <String, String>型別的陣列(List)_imageNames 以及一個狀態變數陣列控制下標_index。當切換按鈕點選時,會在_onSwitch 方法中通過 setState更改狀態變數_index 的值,從而引起介面的自動重新整理。
頁面元件的元素和層級如下:
- appBar:導航欄
- body:主介面
- Center:居中元件
- Container:頁面元素容器,類似 html 的 div,通過這個 Container 指定介面中的尺寸和邊距
- Column:縱向佈局,即元素按縱向一次排布。
- 圖片容器:用於限定圖片的顯示大小,邊距等
- 圖片:使用本地資源展示圖片
- 文字:顯示圖片底下的文字
- 圖片容器:用於限定圖片的顯示大小,邊距等
- Column:縱向佈局,即元素按縱向一次排布。
- Container:頁面元素容器,類似 html 的 div,通過這個 Container 指定介面中的尺寸和邊距
- Center:居中元件
- floatingActionButton:懸浮按鈕
可以看到整個頁面的層次和 HTML 很像,實際上 Dart 最開始的設計就是想替換 Javascript 的,而 Flutter 本身很多理念仿照了 React。從程式碼也可以看到,介面的巢狀層級很多,這被很多人吐槽,實際只要我們將元件抽離,就可以有效減少巢狀層級(介面的寫法也有點類似 JSX,只是Flutter 內建了很多佈局元件,簡化了開發)。
最終效果
點選切換按鈕圖片和文字會隨之變化