Flutter 初體驗
來自專欄 FE-player5 人贊了文章
本文首發於loveky的流水賬
初識 Flutter 還是在上個月的 GMTC 大會上。來自 Google 的工程師現場演示了如何使用 Flutter 構建美觀、高性能的移動應用。個人對其中一些特性,比如良好的開發者體驗、優秀的跨平台能力很感興趣。於是決定在會後親自體驗一下。
最近幾天嘗試使用 Flutter 把京東 APP 中的排行榜頻道的首屏布局實現了一下,算是對基於 Flutter 的開發有了一個最簡單的了解,特地記錄一下,方便其他想了解、嘗試 Flutter 框架的小夥伴。
首先看看我實現了一個什麼樣的界面:
接下來讓我們從不同方面說說 Flutter 的開發。
Flutter 開發環境搭建
安裝 Flutter
不同平台的安裝流程基本一致,這裡就以 macOS 為例。首先下載 flutter macOS 版,並解壓。
把 Flutter 的 bin
目錄添加到系統 PATH
中:
export PATH=~/Software/flutter/bin:$PATH
提示:記得把這行代碼放到你的 shell 啟動腳本中,避免每次都要手動執行。
路徑添加完成後就可以執行 flutter
命令啦。 Flutter 提供了一個 flutter doctor
命令協助我們安裝 Flutter 的依賴。它會檢查本地是否有 iOS 和 Android 的開發環境。如果檢測到依賴缺失,它還會給出對應依賴的安裝方法。你只需要不斷執行該方法,然後安裝缺失的依賴,直到全部依賴安裝完成即可。
配置代碼編輯器
主要是給 IDE 安裝相關插件。
VS Code 上只需要安裝 flutter 擴展即可。
Android Studio 上需要安裝 flutter 和 dart 兩個插件。這裡簡單說一下兩個 IDE 的差異。從開發過程來說,VS Code 完勝 Android Studio。VS Code 提供了非常好的代碼提示功能。以下圖為例,滑鼠移到某個對象或方法上,VS Code 會給出非常詳細的信息。
而在 Android Studio 中,或許是 Android Studio 上的 dart 插件目前功能還不夠完善的原因,IDE 能提供給我的只有一行乾癟的函數簽名。
在調試階段,兩款 IDE 都提供了完善的斷點調試機制。區別在於,Android Studio 還提供了一個名為 Flutter Inspector 的工具。你可以把它理解成為 Flutter 版的審查元素。
綜合以上幾點,目前我在編寫代碼以及調試簡單的邏輯問題時會使用 VS Code,在遇到布局問題時會啟動 Android Studio。具體的選擇大家根據自己的個人喜好決定即可。
配置依賴源鏡像
Flutter 項目有兩個依賴源。
第一個就是 Flutter 框架自身的源。每當 Flutter 框架更新後,我們可以從源中更新最新的 Flutter 框架代碼。
此外,由於 Flutter 使用 Dart 作為其開發語言。Dart 語言的 packages 統一在 https://pub.dartlang.org/ 維護,這就是第二個依賴源。這兩個源目前都是由 Google 在維護,而由於眾所周知的原因,從國內訪問 Google 的服務非常的不穩定。因此需要配置這兩個源的國內鏡像:
export PUB_HOSTED_URL=https://pub.flutter-io.cnexport FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
提示:記得把這些代碼放到你的 shell 啟動腳本中,避免每次都要手動執行。
配置調試設備
調試設備又分為兩類:真機 or 模擬器。我們分別介紹。
iOS 模擬器
這一項是唯一一個不需要任何配置的。只要按照之前的步驟正確安裝依賴。直接在 IDE 中開始調試就會自動啟動一個 iPhone X 的模擬器。
Android 模擬器
Android Studio 默認是不帶設備模擬器的,需要手動添加。
- 啟動 Android Studio
- Tools -> AVD Manager
- 點擊 「Create Virtual Devices...」
- 選擇一個手機型號(其實就是一個屏幕解析度和像素密度的組合),點擊「Next」
- 選擇並下載一個 Android 鏡像。點擊「Next」
- 點擊「Finish」完成虛擬設備的創建。
iOS 真機
需要分別在電腦端和手機端進行配置。
電腦端
進入項目目錄,執行命令:
open ios/Runner.xcworkspace
在彈出的 Xcode 界面依次執行以下操作:
注意:這裡說的開發者賬號可以是你個人的 Apple ID,不必是花 99 刀購買的正式的開發者賬號。
手機端
在完成電腦端的配置後,使用數據線將 iOS 設備接入電腦。如果彈出「要信任此電腦嗎?」的彈框,請選擇「信任」。
然後進入 iOS 的設置界面,依次進入 「通用」 -> 「描述文件與設備管理」。在這個界面你會看到一個以你 Apple ID 命名的開發者應用證書,選擇信任。
至此 iOS 的真機調試就配置完成了。
Android 真機
電腦端
如果是 Windows 系統,請安裝 Google USB Driver。其他操作系統無需特殊配置。
手機端
- 開啟「開發者模式」和「USB調試」選項。
- 將手機通過數據線連接電腦,如果提示「是否允許USB調試」,選擇「是」。
至此,Flutter 的開發環境就基本搭建完成了。
Dart
在說 Flutter 之前,先來聊聊 Flutter 項目的開發語言 —— Dart。Dart 是由 Google 開發的一種面向對象語言。它也可以編譯成 JavaScript,也有類型系統。很多人可能會把它和 TypeScript 比較,兩者在這兩點上還是很相似的。這裡簡單說一下。
TypeScript 是 JavaScript 的超集。這意味所有的 JavaScript 代碼也都是合法的 TypeScript 代碼。TypeScript 在原有 JavaScript 語法的基礎之上提供了一套靜態類型檢查系統,可以幫助我們有效的減少由類型不一致導致的代碼問題。另外,TypeScript 必須編譯成 JavaScript 才可以被執行。
Dart 本身除了可以編譯成 JavaScript 外就和 JavaScript 沒什麼關係了。它其實是一門完全獨立的語言。除了編譯成 JavaScript 在 JavaScript 引擎上執行外,Dart 還可以編譯成 ARM 和 x86 代碼直接運行在 iOS、Android 設備上。Dart 同時支持 JIT 和 AOT。
由於是一門完全獨立的語言,和 JavaScript 沒有任何關係,在學習的過程中請時刻保持清晰的思路。不要把兩個語言中類似的概念混淆,否則很容易造成困擾。
學習資源的話推薦官方的這篇 A Tour of the Dart Language。Dart 語言中最基礎,最常用的語法都有介紹。建議一開始通讀一遍。
在具體使用過程中如果對某個類的某個方法不清楚,可以去 Dart SDK 文檔站搜索具體的類查看完整的文檔。
最後,如果你疑惑 Google 為何會選擇一個非常冷門的 Dart 而不是更為流行的 JavaScript/TypeScript 作為 Flutter 框架的開發語言,那麼強烈推薦你閱讀這篇由 Flutter 團隊成員寫的 Why Flutter Uses Dart。
Flutter
終於,終於要說到 Flutter 框架自身了。由於這兩天的開發過程中其實也只是使用了 Flutter 框架中很少的一部分功能。所以這裡只就我認為對 Flutter 入門最需要理解的兩點來展開聊聊。
Widget
在 Flutter 中所有展示在頁面上的元素其實都是一個 Widget。整個 APP/頁面對應一個頂級 Widget。
根據 Widget 內部是否存在可變狀態,在 Flutter 中又可分為 StatelessWidget 和 StatefulWidget。
顧名思義,StatelessWidget 就是指無可變狀態的 Widget。換句話說,這類 Widget 的狀態只由創建 Widget 時傳入的參數決定,一旦創建,其狀態、在頁面上的展示效果也就不再改變。
而 StatefulWidget 內部則存在著可變狀態。當這些狀態改變時,Flutter 會重新渲染該 Widget。
在實際項目開發過程中,我們要做的就是根據實際需求開發不同的 Widget,並將這些 Widget 組合嵌套以形成一個完整的頁面。在開發之前我們首先要做的就是根據頁面的功能劃分不同的功能模塊,將這些模塊細分成眾多獨立的 Widget。然後再逐一實現其邏輯。
布局、樣式
首先從宏觀上來說,Flutter 中的布局、樣式中絕大多數的概念其實還是沿用了 CSS 中的概念。例如在布局方面與 CSS 中 flex 布局對應的有 Row、Column 兩個 Widget,分別提供了水平和垂直兩個方向的布局方式。再比如 Stack Widget 提供了一種 Widget 之間相互堆疊的機制,這又和 CSS 中的 position: absolute;
很像。
點此查看 Flutter 中所有和布局相關的 Widget。
概念上的相似是不是就可以讓我們輕鬆上手了呢?其實並不是,因為在具體的代碼層面,為 Flutter 中的 Widget 添加樣式 和為一個 HTML 元素添加樣式還是有著很大的差別。這些差別主要表現在以下兩個方面:
不是所有 Widget 都可以添加任意的樣式屬性。舉例來說,如果你想給一段文字添加一個 border。你必須創建一個 Container,把這段文字設置為這個 Container 的 child。然後給這個 Container 設置一個 BoxDecoration 屬性,並在該屬性中設置具體的邊框樣式。像下面這樣:
Container( decoration: BoxDecoration( border: Border.all(color: Colors.red) ), child: new Text("My Awesome Border"),)
由於 Dart 面向對象的特點,基本上所有的樣式屬性都不支持以字元串的形式書寫,而是必須創建特定類的實例或是使用 Flutter 中預先定義好的常量,再看一個例子:
ListView.builder( scrollDirection: Axis.horizontal, padding: EdgeInsets.all(10.0), itemCount: subCategories.length, itemBuilder: (BuildContext context, int index) { })
這裡為了指定 ListView 的滾動方向,我們使用了 Flutter 中預先定義好的 Axis.horizontal
常量,為了表示 4 個方向上的 padding 值,我們創建了一個 EdgeInsets
類的實例。
以上兩個方面在我們剛開始使用 Flutter 開發時會造成一定的困擾,大可不必慌張。只需要一段時間的適應過程,適應之後再配合 IDE 的智能提示功能,開發效率可以得到很大的提升。
以上就是過去幾天我在嘗試使用 Flutter 框架開發一個完整頁面的過程中積累的一些經驗和思考。歡迎對 Flutter 感興趣的小夥伴一起學習,討論。
推薦閱讀:
※Flutter——谷歌開源的跨平台UI開發框架
※深入了解Flutter界面開發
※Android Studio 嘗試 Flutter Demo
※Android Flutter實踐內存初探
※React Native VS Flutter評測