前言
近期有不少網友咨詢 Flutter 學習相關的問題,Flutter 作為一門新的技術,確實相關的資料書籍不太多。但就 Flutter 生態的影響力而言,已經是越來越強了。譬如,在 StackOverflow 網站上2021年度最受歡迎的技術中,Dart 語言排在了第7位。隨著谷歌對 Flutter 跨平臺解決方案的推進,估計會有越來越多的開發者使用 Flutter 構建他們的應用。
本篇,就學習 Flutter 來一次完整的梳理,也歡迎大家在評論區進行補充和交流。
學習線路思維導圖
先上一份思維導圖,讓大家有個整體認識。
Dart 語言
在學習 Dart 語言前,若沒有任何編程基礎,建議先了解一下計算機基礎知識。Dart 作為一門現代化的面向對象編程語言,具備了市面上大多數編程語言的特點,具體來說會分為下面這些內容:
- 變量定義、賦值:這是最基礎的部分,至少要知道什么是變量,如何賦值。final,var 和 const 的區別。
- 基本數學運算:加、減、乘、除、整除、取余等運算;
- 條件分支:if...else if...else 控制程序邏輯走向,或是 switch 分支;
- 循環:使用循環完成重復性的工作;
- 容器類:如List、Map 和 Set 的應用;
- 函數和參數:一個是使用函數編寫可復用的邏輯處理代碼,二是需要注意在 Dart 中函數也是對象。同時需要區分函數的命名參數、可選參數的使用;
- 面向對象編程:了解面向對象編程的概念和思想,能夠合理地使用類來封裝代碼提高復用性和降低耦合;
- 繼承、多態和抽象類:這是提高代碼復用、降低代碼耦合度十分重要的概念,建議是多看看一些源碼和設計思想(如設計模式),然后在遇到復雜業務的時候先思考如何抽象和組織代碼結構。
- mixin:mixin 提供了一種更為靈活的代碼復用方式,可以將功能組合到現有類中,從而避免了繼承的一些缺點。
- 泛型:使用泛型來做工具類是再好不過的選擇了,通過泛型可以一套代碼處理多種數據類型。
- Future:有點類似前端的 promise,通過 Future 可以讓異步編程變得更加簡單。
- null safety:空安全現在基本上是高級語言的標配了。通過空安全可以讓團隊遵循同一個規范,提高了代碼的健壯性。
Flutter 組件
作為一個合格的App 開發,能夠將一個UI 界面還原出來是基本的要求。建議一開始需要熟悉Flutter框架提供的自帶組件,然后可以通過自帶的組件組合成為自己的自定義組件。這部分內容包括:
- 運行 Hello World 程序,跑通整個應用。
- 了解應用程序的結構,知道如何設計你的代碼目錄結構。
- 布局類組件:如
Container
,SizedBox
,Padding
,Stack
,ListView
,GridView
等組件。 - 業務類組件:如
TextField
,按鈕,文本,圖片,圖標等組件。 - 自定義組件:利用布局類組件和業務類組件組合,構成自己的可復用的組件。
- 自有組件庫:根據產品特性和公司需要,抽取復用的組件構成自有的組件庫,從而提升整個公司的開發效率。
表單
應用中,表單在界面中出現的頻率很高。如何處理表單對開發效率的影響很大。建議可以一開始從簡單的表單頁面開始,例如登錄頁、注冊頁。然后再做一些復雜的表單頁面,具體如下:
- 簡單表單頁面的實現:登錄頁、注冊頁、綁定手機號這類的頁面;
- 不同表單的實現:例如普通文本、密碼、數字、日期、單選、多選等表單的實現;
- 表單校驗:封裝表單校驗庫,將通用的校驗規則放置在校驗庫中,比如長度、手機號校驗、密碼強度校驗、日期格式校驗等等。通過前端的提前校驗可以避免后端請求壓力,也能夠提升用戶體驗。
- 表單封裝:封裝一套通用的表單組件,供整個團隊復用,提高生產效率,也能減少 bug 的產生。
狀態管理
狀態管理是 Flutter 的核心,如何處理數據實體、業務邏輯、界面之間的關系對代碼的可維護性十分關鍵,而這都依賴于狀態管理的實現。對于狀態管理,建議按如下方式學習:
- 有狀態組件和無狀態組件的區別,可以閱讀一下
StatefulWidget
和StatelessWidget
的源碼,會有更深刻的理解。 - 理解組件的渲染機制:雖然我們開發中很少關注組件如何渲染,但是當應用狀態管理插件時,我們通過渲染機制能夠知道狀態數據更新時如何減少刷新的范圍,實現局部刷新,從而提升性能。
- 主流狀態插件應用:對比主流狀態插件,從中選擇一個合適自己團隊的應用。對于長期用的狀態管理插件,建議深入了解具體的實現機制,以便再遇到問題時能夠快速定位,快速解決。
- 按需刷新:相比
setState
這種簡單粗暴的全局更新,狀態管理插件的一大優勢就是可以實現局部刷新。通過按需刷新可以極大地提高頁面的流暢度。
關于狀態管理的插件,可以通過閱讀下面這篇文章來進行了解。也可以閱讀我的系列專欄,有介紹常用的狀態管理插件使用和原理。
網絡請求
App 的業務功能開發,相當一部分工作是在與和后端對接口、聯調接口。了解與后端的數據交互,封裝好網絡請求庫非常重要。這里建議按如下的方式進行學習:
- JSON 數據的認識:這個其實很簡單,基本上一看就明白。但更重要的是和后端約定返回數據的格式,避免每個接口的格式都不同,那樣很難做統一封裝。
- JSON 數據轉對象:曾幾何時,我是直接拿 JSON 對象(實際已經轉成 Map 了)的 key 去取所需的值的。結果遭受了慘痛的教訓,比如后端問題變成 null 了會導致閃退。而且每次都需要敲 key的名稱,編碼效率極低。而將 JSON 數據轉為對象,一方面是對象可以在整個工程里復用,二是可以通過對象屬性訪問,編碼有提示。同時,可以應用 null safety 屬性直接知道哪個屬性是否可能為空。
- RESTful接口調試:早期的接口都是 GET 和 POST 請求,但是其實語義上并不明確。建議是統一和后端約定使用 RESTful 風格接口。
- Mock 數據:后端接口沒出來之前,使用 Mock 數據來完成業務邏輯的模擬非常重要。建議 Mock 的數據獲取接口和后端的接口保持一致(統一實現相同的接口),這樣在后端接口就緒后可以直接切換接口實現類就可以了。
- 網絡請求插件使用與封裝:Flutter 目前最為流行的網絡請求插件是 Dio,對應的封裝版本有 Retrofit。建議不要上來一開始就有用封裝好的版本。而是自己一個個調試,然后嘗試自己封裝,這樣會更好地理解封裝的過程。
-
Headers
和Cookie
:App 和瀏覽器不同,瀏覽器會自己管理Cookie
。而 App 需要自己管理Cookie
。因此有必要了解如何設置請求頭Headers
,以及如何獲取后端的Cookie
并回寫到Headers
里面。
響應式編程
當你對界面、狀態管理、網絡請求都掌握差不多到時候,使用 Flutter 開發基本的 App 就基本沒問題了。這個時候需要考慮應用結構如何優化。對于 Dart 而言,提供了 Stream 和 StreamListener 這樣的工具來通過流的方式驅動關聯業務或界面更新,實現響應式編程。這里面典型的是 BLoC 模式 (BLoC 也可以用于狀態管理)。了解一下 BLoC 的理念對設計整個應用程序框架十分有幫助。
動畫
當你掌握上述的基本技能后,你看到別人 App 的酷炫動效時肯定心癢癢,想自己偶爾也能玩一下這類高大上的東西。這個時候就需要了解動畫的實現了,Flutter 提供了很多動畫構建方式,比如:
- 基礎動畫組件:例如
AnimatedContainer
,AnimatedOpacity
等等,通過這些組件可以實現簡單但有趣的動畫。 - 動畫復用:使用
AnimatedBuilder
可以構建可復用的動效。 - 動畫曲線:Flutter 自帶了很多動畫曲線效果,如果不滿足也可以實現自定義曲線。有了動畫曲線,你就可以定義一些自己的動畫過渡效果了。
- 動畫插件:pub上也提供了很多動畫插件,例如
Lottie
就可以將 AE 的動畫轉換為 Flutter 動畫。如何查找動畫插件,這需要懂得搜索,比如搜索關鍵字Animation
,或者經常逛一些技術社區,會讓你的視野開拓很多,也許,不經意間就能發現一個酷炫的插件。
繪圖
當你的動畫都能搞定的時候,你會發現產品和設計可能已經對你刮目想看了,這個時候他們提出的交互或者界面效果會提高(千萬別覺得升級自己的技能是在給自己挖坑)。比如,可能會出一個奇怪的外形,然后需要你實現,這個時候就需要用到繪圖了。繪圖其實需要挺高的數學知識輔助的,你可能需要提前復習一下高等數學、線性代數知識?????? —— 所以大廠篩選學校和學歷其實也有一定的道理的,這些篩選出來的人的基礎知識一般都不會差。
-
ClipPath
:自定義裁剪路徑對于繪制有規律的形狀來說可以輕松搞定,當然有些復雜的可能需要一些貝塞爾曲線知識。 -
CustomPaint
和Canvas
:使用CustomPaint
和Canvas
可以隨心所欲地繪圖,包括你想搞個小游戲也行。但是,這個也是很燒腦的一環,說到底,數學真的很重要! - 計算機圖形學(CG):這算是繪圖的理論支撐,有計算機圖形學知識的支撐,會讓你繪制自定義圖形時候得心應手。
本地數據存儲
隨著網絡的升級,本地數據存儲可能不像之前那么重要。但是,不論是對用戶體驗還是減輕后端壓力都是必不可少的。譬如,微信就把整個個人的聊天記錄存儲在了本地 —— 既節省了服務器的存儲空間和加載請求量,還能夠對外宣稱是“保護個人隱私”。本地存儲主要有三個方面:
- 簡單鍵值對的存儲:可以存儲一些配置信息、登錄會話信息,避免反復從服務器讀取。在 Flutter 通常是使用
SharedPreferences
實現。 - 文件存儲:比如應用內下載的文件管理,日志文件等,可以使用文件管理實現。通常會使用到
path_provider
插件實現。 - 關系型數據庫:移動端大部分都采用了 SQLite 數據庫,SQLite 的數據庫操作語法和 MySQL 這類的標準 SQL 基本一致,可以用于存儲關系數據。在 Flutter 中也有不少封裝好的插件,比如 sqflite。
頁面導航
實際上頁面導航在一開始就會用到,大部分情況下,自帶的導航和路由管理都能夠滿足需求。對于路由可以按如下方式進階:
- 自帶路由的掌握:比如匿名路由,命名路由,路由傳參,路由攔截等;
- 路由插件的應用:了解如 fluro、GetX 的路由管理的優缺點,選擇使用自帶的路由管理還是使用第三方插件。
- 2.0路由:這個如果是在 Web端的話建議了解一下,App 端個人感覺有點重,學習成本相對較高。當然,因為剛出來沒多久,估計以后也會有簡單易用的插件幫助我們使用。
自有插件
如果你的公司業務條線比較多,也許此時已經成為公司大神的你會被邀請做基礎設施建設,或者是你自己想為開源社區做做貢獻,這個時候就需要構建自有插件或開源插件了。Flutter 提供了插件構建模板工程,你可以按步驟構建自有插件,然后供整個公司的各個業務條線使用,提高各個業務條線的生產力。
原生交互
原生交互分為三個部分:
- Flutter為原生提供服務
- Flutter 使用原生提供的接口
- 原生頁面與 Flutter 頁面之間的跳轉
這塊對于混編的應用來說是必不可少的,此時你的知識體系需要升級了,你需要學習安卓的 kotlin 開發,iOS 的 Swift 開發(呃,本來想一站式搞定,結果又繞回來了)。當然,到這個階段,相信這些已經難不倒你了!
應用發布
恭喜你!你的應用可以在各大應用市場上架了!記得我的第一個應用在 AppStore過審的時候別提多興奮了(之前被拒了好幾次??????)!如何進行應用打包這個搜索一下就能搞定了,但是如何應對AppStore 每年都變的審查規則也是一場斗智斗勇的過程。 而安卓,如果搞定碎片化的操作系統分布也是頭疼的一件事情。建議提前在應用內做應用統計,以及異常上報,避免發布后在用戶機器上出現奇怪的問題。
后續
技術永無止境,再往后,你可能會深入去做性能優化、應用架構設計。這些方面很大程度靠個人平時的積累,多輸入新的知識,同時了解其他的應用框架和特性(不限于 Dart,比如 Java 的 Spring 框架,Web 端的 React、Vue)都會讓你對當前的應用架構設計有新的認識。擴充視野和技術深度,也許你就是下一個 CTO 的人選????????????!!!