Flutter:从入门到实践
課程內容
開篇:迎合未來主流趨勢,把握新技術主動權
移動開發的前方突破口在哪里?
小團隊如何面向未來做技術選型?
想要獨立開發一個產品,能不能做到省心省力?
我用兩個關鍵詞來回答這些問題:跨平臺、Flutter。
背景
最近,Flutter 在前端和移動開發圈里引起了不小的熱度,阮一峰老師也專門發表了一篇博文。
因為,谷歌官方正式宣布 Flutter 全面支持多平臺,包括移動平臺 Android/iOS、Web( 新發布 )、桌面 PC 平臺(內測中)、嵌入式平臺(內測中)。
Flutter 具有高擴展性和高性能。可以預見,這門顛覆性編程技術將成為未來主流。一套代碼邏輯規范實現全平臺開發!不過 Flutter 起步于移動端、目前重心也在移動平臺,其他平臺 Google Flutter 團隊正在逐步拓展完善。所以學習 Flutter 我們也先從移動端的開發學起。
跨平臺是趨勢
現在技術更新非常快,可能幾年內就會有一個新的技術出現。移動端、前端、后端開發領域的邊界逐漸模糊,要求一個開發者掌掌握多端開發的場景也越來越多,所以跨平臺開發技術層出不窮。
為什么會這樣呢?我們可以來分析一下。
首先,節約成本的優先選擇(用人單位的需求)。
互聯網行業撿錢的時代已經過去了,現在的公司紛紛選擇精簡人員配置,尤其對于規模不大的公司來說,開發一個產品要投放各平臺,至少需要一個 Web 端開發,一個 Android 開發,一個 iOS 開發,人力成本相當高。因此,在跨平臺實現效果與原生開發效果的差別愈發縮小的時候,很多公司更傾向于采用跨平臺開發。
反之,對于開發者個人,去提前了解甚至掌握基本的跨平臺開發技術,不但能補足自己的技術棧,還能在趨勢早期創造明顯的就業優勢。
其次,設備的發展造成了需求(使用者的需求)。
我們都有體會,以前計算機語言和技術出現和迭代的頻率并沒有這么高。我認為,其中一個重要因素是硬件設備的制造門檻越來越低,計算機運算速度越來越快。
現在,計算機運算速度提高到了恐怖的程度,它縮小甚至抹平了很多技術的差距,導致不同技術呈現效果幾乎相同。設備形態也五花八門多種多樣,人們使用著不同尺寸和特點的設備,自然希望自己慣用的某一款產品,在這些設備上都能流暢地打開和使用。難道每增加一個新設備,就要配備一個專門的開發工程師嗎?
還有,技術的發展提供了可能性(開發者的需求)。
原有的技術為了迎合使用者的需求,正在不斷地更新迭代,與此同時,大量新的技術和語言也在孕育和產生。它們的目標都是更便捷、更高效的開發。
面對產品提出的各種需求,為了提高開發效率,開發者們是傾向于使用包容性強、適配性好的語言和技術。
整個分析下來,可以看到,跨平臺正是大勢所趨。
而 Flutter 的出現讓跨平臺移動端的接近原生的高性能體驗成為可能,并不斷在擴展 Web 端、PC 端等平臺。
Flutter 是趨勢
Flutter: a Portable UI Framework for Mobile, Web, Embedded, and Desktop.
(Flutter,一個支持手機、網頁、可嵌入設備、和桌面的可移植 UI 框架。)
Flutter 是 Google 力推的跨平臺框架,將是未來的 Google Fuchsia OS 下開發應用的主要技術框架。
谷歌對 Flutter 的投入非常大,SDK 的更新頻率也很高。2019 年 5 月 8 號,谷歌剛剛發布了 Flutter 1.5 穩定版。
Flutter 的開發將不僅僅局限于移動跨平臺,目前已經支持 Web 開發、后端開發、PC 桌面應用開發(內測中)、嵌入式開發(內測中)。
Google 的消息推出后,阮一峰老師也第一時間表達了他對 Flutter 的看好:
"我的看法是,如果現在學習跨平臺應用開發,第一個要看的不是 React Native,而是 Flutter。"
其實,撇開個人開發者,許多大公司早就率先嘗試了 Flutter。國內的阿里巴巴、騰訊、愛奇藝等大公司已經把 Flutter 應用在實際開發中,例如閑魚團隊已經把 Flutter 技術應用在閑魚應用上。
那 Flutter 開發體驗如何?
- Flutter 入門容易
Flutter 基于 Dart 語言編寫,有 React 語言風格,又結合 JavaScript、Java 優點,有面向對象開發語言基礎的同學,很容易就上手了。
- Flutter 真正跨平臺
除了原生外,目前跨平臺技術一般是混合開發,如采用 H5、React Native、Weex、小程序等技術。不過這些或多或少都能感覺到卡頓和體驗不流暢,并且開發和學習成本非常高,而且都有各自的局限性。
Flutter 既能用原生代碼直接調用的方式來加速圖形渲染和 UI 繪制,又能同時運行在兩大主流移動操作系統上。看下幾種方案的對比情況:
| Flutter | 高,接近原生體驗 | 高 | Skia 高性能自繪引擎 | 低,Widget 組件化 | 高,采用插件化的庫進行擴展 |
| RN/Weex/小程序 | 有延遲,一般 | 一般,復雜、效率低 | Js驅動原生渲染 | 高,復雜 | 一般 |
| 原生應用 | 高 | 一般 | 原生渲染 | 高,需要學習 Android 和 iOS 原生 API | 高 |
從上面的對比可以看出,Flutter 的優勢明顯:高體驗度、高開發效率、低學習成本、高可擴展性,未來 Google Flutter 團隊還將使 Flutter 支持 PC 和 Web 的跨平臺開發,真正全平臺。
- Flutter 用戶體驗媲美原生
可以說 Flutter 是一個革命性、創新性的技術框架,它實現了一套語言實現 Android 和 iOS 終端平臺的高效開發,并且非 Web 跨平臺模式,而是采用全新渲染引擎 Skia。它實現的應用體驗和原生基本一致,流暢度遠遠高于目前的小程序、React 等技術方案,官方公布可以達到 60 FPS,甚至要高于原生的流暢度體驗。
- Flutter 開發過程輕松
太多開發者的切身實踐證明,Flutter 的開發體驗也相當不錯!
I wrote nicer, more maintainable code that runs on both iOS and Android. It also took considerably less time and fewer lines of code to do so.
(我編寫了更漂亮、更易于維護的代碼,可以同時運行在 iOS 和 Android 上。 它只花費了我相當少的時間和比原生開發更少的代碼行。)
——Why Flutter Will Change Mobile Development for the Best
基于原生開發的 SDK,能輕松寫出同時運行在 Android/iOS 的代碼。
Flutter 成為未來主流跨平臺開發框架技術已經勢在必行,它開發高效、性能優秀、更新頻率快、插件三方庫支持多、Google 團隊的技術支持給力、一套代碼多終端運行,這些都非常的吸引人。
最后總結下,Flutter 全面網羅 Web、Android、iOS、Windows、linux、桌面、瀏覽器甚至物聯網設備,未來趨勢是屬于 Flutter 的!
課程大綱
本課程主要面向有開發經驗 1 年及以上的開發者,或者想轉入學習 Flutter Dart 的開發者,不限語言。
課程內容注重基礎入門,在學習的深度和廣度上都有很好的權衡,幫助大家高效學習 Flutter 編程。課程按照編程思維規劃學習路徑,可以讓我們的學習事半功倍,少走彎路。每一章節內容都按照 Google 官方源碼和文檔編寫實例,既保留官方的原汁原味,又加入相關輔助學習的案例與注釋,可以邊學習邊實踐。
本課程大綱分為四大部分,共計 39 篇,分階段講解 Flutter 框架。
第一部分:Flutter 和 Dart 初探
主要是 Flutter 和 Dart 介紹、最高效的開發工具和環境的搭建、模擬器安裝和調試、編譯和打包應用、項目結構介紹、配置文件詳解、開發規范、基礎組件講解、基礎布局講解等等。
讓你快速地進入一個嶄新的技術和語言的學習中,了解它的基礎中的重點核心部分。
第二部分:Flutter 核心 Widget 應用
主要講解 Flutter 的核心常用 Widget、路由、HTTP 網絡請求詳解(3 種 POST 和 1 種 GET)、WebSocket、JSON 編解碼、文件和圖片讀寫操作詳解、手勢和數據庫緩存詳解、動畫、應用國際化等。
每一部分都是實例講解學習,都是精心設計案例。并且實例里面涵蓋了官方的大部分 API 的用法,還擴展了其他常用的 API,讓你學習到官方文檔上沒有詳細講解到的 API 用法。
第三部分:Flutter 開發深入
第三部分主要講解了自定義 Widget、原生和 Flutter 交互、編寫 Flutter Plugin 框架、Flutter 調試、Android 和 iOS 的打包、Dart2 的 Web 開發、Dart Pub 倉庫的使用和提交等。最后有一個完整的小應用的實踐,綜合了整個知識點。
第四部分:Flutter 擴展實踐
第四部分是應用實踐的擴展,包括類似音視頻播放、權限處理、狀態管理如何實踐,使學習者的實踐技能更加豐富。
寄語
介紹了這么多,相信未來幾年大家可以在熱門編程語言/跨平臺框架排行榜的前幾名上看到 Dart 和 Flutter。本套 Flutter 開發系列課程,可以讓你學習 Flutter 事半功倍,更加高效、更加快速地認識和學習這門新技術、新語言、新語法!
希望每一位學習本課程的學習者,能夠在技術上有所收獲,在心態上更加自信。學習 Flutter,迎合未來主流趨勢,贏得新技術主動權!
如果大家有什么更好的建議或者疑問,都可以溝通和交流,一起學習一起進步,加油!
點擊了解更多《Flutter:從入門到實踐》
第 1-1 課:為什么要掌握 Flutter?
移動開發技術手段從原始的原生應用開發,到 Google 和 Apple 各自推出新的語言 Kotiln、Swift,然后又發展到各種跨平臺Hybrid App 開發,如 React Native、Weex、小程序等等。不過這些方案或多或少都有一些局限性和缺點,于是 Google 推出了新的跨平臺移動應用開發技術:Flutter。
為什么說 Flutter 將是未來的主流跨平臺開發框架?
Google 的 Flutter 開發應用的體驗和流暢度基本和原生體驗一致,感覺不到不流暢和卡頓。
我們知道在移動平臺上,原生應用的體驗最好、流暢度最高、性能也最好。而目前的跨平臺技術和框架的流暢度和體驗遠遠達不到原生的體驗,多少都會卡頓和丟幀,但是 Google 官方說 Flutter 可以達到120 FPS。
Flutter 最出色的地方就是自建了繪制引擎,使得跨平臺開發一套代碼可以創造出和原生應用相同的體驗。并且 Flutter 開發效率非常高,SDK 里所有的布局、控件都組件化,采用 React 方式。
Flutter 的開發不僅僅局限于移動跨平臺,目前已經支持 Web 開發、后端開發、PC 桌面應用開發(內測中)、嵌入式開發(內測中)。 這也是 Flutter 變得越來越受關注,越來越多大公司和開發者進行使用的原因之一。
Flutter 支持多種開發工具的插件化使用,這就大大的豐富了各種開發工具可以進行 Flutter 的開發和調試,也滿足了不同開發者的開發習慣。
同時 Flutter 不但做到了一套代碼邏輯實現 Android 和 iOS 平臺的跨平臺運行,而且無需像 React Native 等技術那樣,部分和原生交互的邏輯需要寫兩套代碼邏輯,Flutter 只需寫一套代碼,大部分功能官方 SDK 里已經支持,并在不斷更新拓展。而且如果需要一些與原生交互的部分,都是通過插件化形式使用,依然是一套代碼邏輯多平臺兼容。后面將會詳細講解。
接下來,我們就開始我們的認識 Flutter 技術之旅吧。本文將主要介紹:
- Flutter 的誕生
- 目前各種跨平臺方案的對比
- Flutter 特點
- Flutter 框架結構
- Flutter社區活躍度和趨勢
1 Flutter 的誕生
( 圖片來自 Google 開發者官方 )
Flutter是 Google 于 2015 年 5 月 3 日推出的免費開源跨平臺開發框架,可以快速開發 Android 和 iOS 應用,同時也將是未來的 Google Fuchsia OS 下開發應用的主要技術框架。未來的 Flutter 的開發不僅僅局限于移動跨平臺,目前已經支持 Web 開發、后端開發、PC 桌面應用開發(內測中)、嵌入式開發(內測中)。
Flutter 的第一個版本 SDK 運行在 Android 操作系統上,被稱作“Sky”。第一個開發者版本在 2015 年的 Flutter 開發者會議上被公布,并且對外宣稱 Flutter 的開發的應用目標為實現 120FPS的渲染性能,原生的渲染性能一般為 80FPS。由于之前一直是開發版本,所以 Flutter 不溫不火,只有少數的一些公司和 Google 內部在嘗試使用。
終于在 2018 年 12 月 5 日,Google Flutter 團隊正式發布了 Flutter 1.0 正式版,正式版的發布意味著 Flutter 在經過開發、測試、應用上已經基本上穩定和滿足大部分開發需求了。這也使得Flutter 在發布正式版后,更多的大公司、開發者紛紛轉型使用和學習 Flutter 進行跨平臺應用的開發。
目前在 Google 內部,Flutter 已經被廣泛用于多個產品,比如 Google Ads 已經將其產品的 iOS 版本和 Android 版本轉向使用 Flutter。在正式版本之前,全世界已經有多個公司開始使用 Flutter 來開發應用,包括 Abbey Road Studios、阿里巴巴、Capital One、Groupon、Hamilton、京東、Philips Hue、Reflectly 以及騰訊等。而正式版的功能基本上已經比較完善,其他的擴展更強大的功能 Google 官方也正在規劃擴展開發。目前 Flutter 1.5 穩定版已經于 2019 年 5 月 8 號發布,這樣的更新頻率,給更多的開發者和公司增加了動力。Flutter 勢必也將成為未來的跨平臺開發主流趨勢!
接下來回顧下 2018 年和 2019 年 Flutter 的發展情況:
- 2 月底在世界移動大會 (MWC)上宣布了第一個 Beta 版發布;
- 5 月的 Google I/O 大會上發布了 Beta 3;
- 6 月底的 GMTC 宣布了首個發布預覽版;
- 9 月的谷歌開發者大會(Google Developer Days)上,發布預覽版 2。
- 12 月宣布發布正式穩定 1.0 版;
- 2019年 2 月宣布發布穩定版 1.2 版本 SDK。
- 2019年 5 月宣布發布穩定版 1.5 版本 SDK。
作為 Flutter 1.0 之后的首次更新, Flutter SDK 1.2 穩定版圍繞以下幾點進行了重點優化與改進:
- 提升核心框架的穩定性、性能和質量;
- 改進現有 Widget 視覺效果和功能;
- 為 Flutter 開發者提供全新的基于 Web 的調試工具。
目前 Flutter 的社區非常活躍,Flutter 在 Github 最受歡迎的開源軟件中排名前 50,國內也有大量的開發者開始使用 Flutter 構建跨平臺 (Android & iOS) 的應用,如:阿里巴巴、騰訊、京東等都使用 Flutter 發布了自己的應用。
Google 官方 Flutter 團隊計劃,未來也將支持 Flutter Web 和 Flutter PC 的應用移植開發,讓我們拭目以待吧!
2 目前各種跨平臺方案的對比
目前我們在開發應用時,需要同時兼容 iOS 和 Android 兩種平臺時有兩種技術選擇:走原生開發路線,把界面和邏輯在不同平臺分別實現;抑或用同一套代碼兼容多個平臺,但這往往意味著運行速度和產品體驗的損失。除了原生外,目前跨平臺技術一般是混合開發,如采用 H5、React Native、Weex、小程序等技術實現跨平臺應用。不過這些或多或少都能感覺到卡頓和體驗不流暢,并且開發和學習成本非常高,而且都有各自的局限性。
Flutter 的出現就是為我們提供了一套兩全其美的解決方案:既能用原生代碼直接調用的方式來加速圖形渲染和 UI 繪制,又能同時運行在兩大主流移動操作系統上,并且體驗和流暢度和原生基本一致、開發效率也非常高、學習難度和成本低。
那么接下來看下幾種方案的對比情況:
| Flutter | 高,接近原生體驗 | 高 | Skia 高性能自繪引擎 | 低,Widget 組件化 | 高,采用插件化的庫進行擴展 |
| RN/Weex/小程序 | 有延遲,一般 | 一般,復雜、效率低 | JS 驅動原生渲染 | 高,復雜 | 一般 |
| 原生應用 | 高 | 一般 | 原生渲染 | 高,需要學習 Android 和 iOS 原生 API | 高 |
從上面的對比可以看出,Flutter 的優勢明顯:高體驗度、高開發效率、低學習成本、高可擴展性,未來 Google Flutter 團隊還將使 Flutter 支持 PC 和 Web 的跨平臺開發,真正全平臺。 在 Flutter 1.0 正式版本尚未推出之前,已經有成百上千的基于 Flutter 開發的應用在 Apple Store 和 Google Play 上架,相信 Flutter 將會被越來越多的開發者和公司所接受和采用。
3 Flutter 特點
Flutter 是一個框架,基于 Dart 語言編寫,語言風格和 React 很像。Flutter 里幾乎都是采用組件的形式進行構建應用和功能的,組件采用現代響應式框架構建,中心思想是用組件(Widget)構建你的 UI。
一切對象都是組件,Flutter 可以說是全新的技術和平臺框架,學習和開發起來并不難,開發應用的效率也相對于原生提升了很多,并且運行速度和原生幾乎沒太大差別,遠遠高于 HTML 的應用的渲染速度。Flutter 的引擎使用 C++ 開發,基礎庫由 Dart 編寫,提供了用 Flutter 構建應用所需的基本的類和函數。
我們看下 Flutter 官方的架構圖:
( Flutter 官方架構圖 - 來自 Flutter 官方網站 )
可以看出核心引擎是使用 C++ 編寫,上層采用 Dart 語言編寫的 SDK,采用 React 風格組件化方式。并且提供了 Material 和 Cupertino 兩套風格的 UI Widget,使用起來非常方便。
那么接下來我們詳細了解下 Flutter 的特點:
- Flutter 的一個重要的特點就是速度快。它基于 Skia 2D 硬件加速圖形引擎,該引擎也同樣用在了 Chrome 和 Android 平臺。媲美原生應用的速度,讓用戶體驗和流暢度做到更好。Flutter 的代碼基于 Dart 平臺,可以被編譯成 iOS 和 Android 平臺上 32 位和 64 位的 ARM 代碼。
- Flutter 非常高效。Flutter 引入了 Stateful Hot Reload(保持應用狀態的熱重載),這個革命性的新特性可以讓移動開發者和設計師們時時快速預覽應用程序。通過 Stateful Hot Reload,無需重新啟動應用,就可以在程序運行的時候直接看到代碼修改之后的效果。在Flutter官方的用戶反饋中,很多開發者表示這個特性使得開發效率提升了三倍以上。
- Flutter 是開放的、開源的。Flutter 是一個基于 BSD-style 許可的開源項目,全球數百位開發者在為Flutter貢獻代碼。Flutter 的插件生態系統平臺也已經非常的豐富,有數千款插件已經發布,避免了重復造輪子。由于 Flutter 應用程序使用標準的 Android 和 iOS 的編譯打包工具 (build tools),因此它的開放性還體現在我們可以使用原生開發資源和技術。比如,我們依然可以在 Android 上使用 Kotlin 或者 Java,在 IOS 上使用 Swift 或者 Objective-C 來寫邏輯或者界面,使得可以Flutter和原生混合開發。
- Flutter 提供了兩套 UI Widget 風格庫:Material 和 Cupertino,這使得我們可以方便的快速構建 Android 和 iOS 不同平臺風格的應用,大大提升了開發效率。組件化開發風格也使得繪制UI的效率大大提升,學習成本也降低了很多。
- Flutter 支持多種開發工具進行開發,比如 Visual Studio Code、Android Studio、IntelliJ 或其他開發工具,只需要安裝相關的插件即可。
Google Flutter 團隊官方也宣布,Flutter Web SDK(Hummingbird)已經在研發中,我們先來簡單的看下其架構:
目前在 Google I/O 2019 大會當天 Flutter Web SDK 已經正式發布,而且開發出的 Web 性能非常高。
4 Flutter 社區
看一個技術和語言的發展情況和支持情況看它的相關資源、社區等也非常重要。Flutter 技術已經被很多大公司采用,具體案例列表,可以在官方查看:flutter.dev/showcase或https://itsallwidgets.com。
(來自 Flutter 官方:https://flutter.dev/showcase )
我們看下 Flutter 官方 GitHub 的更新情況:
開發者平時可以關注 Github 的更新動態,官方更新頻率也是很快的,這點非常好,也令關注者和使用者對 Flutter 的未來更加有信心,因為社區和生態、更新頻率對開發者非常的有幫助。 遇到問題除了使用搜索引擎搜索外,也可以在官方 GitHub 的 Issues 里進行搜索或者提問。
我們再看下官方版本的更新頻率:
除了這些以外,我們還可以在官方的倉庫進行查找第三方插件庫進行使用:https://pub.dartlang.org/。
里面有非常多的插件庫供我們使用,還配備有相關文檔,當然我們也可以提交自己的開源插件庫到上面。
5 Flutter 未來規劃
就目前而言,Flutter 的首要目標平臺是 iOS 和 Android,但 Flutter官方團隊也在不斷探索將 Flutter 拓展到手機端以外的更多平臺上,如 Web、PC、嵌入式等平臺。實現真正的跨平臺:一套代碼規范多平臺運行。
事實上,Flutter 的設計理念就是希望它可以作為一個靈活且便攜的 UI 工具包,以適應各種需要繪制屏幕內容的平臺。
其中 Flutter 的一些進展已經公布,Flutter Desktop Embedding(google/flutter-desktop-embedding )就是其中的一個,這是一個使 Flutter 運行于 macOS、Linux 和 Windows 等桌面操作系統的項目。前不久,官方嘗試在樹莓派平臺運行了 Flutter 應用,以非正式和探索的形式向用戶展示 Flutter 是有可能運行在一些沒有完整桌面環境的小型設備中的。
除了這些,還有 Flutter Web(Hummingbird)。Hummingbird 是一個基于 Web 實現的 Flutter 運行時環境。它利用了 Dart 語言能被編譯成 JavaScript 的特性。這個項目讓 Flutter 應用程序能夠無需改動就運行在標準 Web 平臺,目前還在開發測試中:
Flutter 團隊也于 2019 年 1 月 27日發布了 2019 年 Flutter 規劃路線。
以下幾點 Flutter 今年會著重關注:
- 核心和基礎
- 易用性
- 生態系統
- 移動端之外的支持
- 動態更新
- 工具鏈
當然,我們也可以提一些反饋給官方:
- 通過 Issues:flutter/issues/new/choose
- 郵件群組:flutter-dev
Flutter 目前有四個版本: master、dev、beta 和 stable,質量和穩定性從前向后依次遞增,發布速度當然也會是依次相對放緩。
官方計劃每個月發布一個 beta 版本,這個發布通常會是在月初,全年會發布四個較大的正式 (stable) 版本。在生產環境里,還是建議大家使用 Flutter 的正式版本。
這個是官方的版本發布流程:flutter/wiki/Release-process
如果大家對 Flutter 每個月將會發布什么感興趣的話,可以在官方 GitHub 上的 milestones 頁面查看:flutter/milestones
( 圖片來自 Google 開發者官方 )
總結
Flutter 現已進入 GitHub Top 20 軟件庫,通過這門課程希望大家可以對 Flutter 進一步了解,并且對它充滿信心,也希望大家有所收獲。
Flutter 成為未來主流跨平臺開發框架技術已經勢在必行,它開發高效、性能優秀、更新頻率快、插件三方庫支持多、Google 團隊的技術支持給力、一套代碼多終端運行,這些都非常的吸引人。
大家可以:
去官方 GitHub 查看官方動態,或者去 Flutter Pub 查看下倉庫的使用方法,以便對 Flutter 有更加深入的了解。
熟悉 Flutter 特點和未來趨勢,做好后續課程的學習和開發的準備。
入門 Flutter,掌握未來技術主流的主動權!
點擊了解更多《Flutter:從入門到實踐》
注意!!! 為了方便學習和技術交流,特意創建了《Flutter:從入門到實踐》的讀者群,入群方式放在 第 1-3、1-4、1-5 課 文末,歡迎已購本課程的同學入群交流。
第 1-2 課:Dart 語言基礎
學習一門編程語言,首頁要了解它的歷史和特點。Dart 是 Google 公司推出的編程語言,于 2011 年就已經亮相了。Dart 也是一門面向對象的語言,語法和 Java、C、JavaScript 很像。所以會 Java 語言,學習 Dart 一般會快一些。
Dart 里所有的類都可以看成是對象,是單繼承,動態類語言。可以進行多平臺開發,我們的主角 Flutter 就是基于 Dart 語言編寫的。本節課程里,我們就開始進行 Dart 語言的基礎語法學習。本文將主要介紹:
- Dart 的特點及簡單介紹
- Dart 的數據類型、操作符、變量常量
- Dart 的運算符、流程控制語句
- Dart 的函數(方法)、類
- Dart 的泛型、接口等
1 Dart 簡單介紹
1.1 為什么要介紹 Dart?
Google 計劃未來的 Flutter 將會是移動應用、Web 應用、PC 應用等平臺的跨平臺高性能框架,也是未來的 Fuchsia 操作系統的主要框架,而 Flutter 是基于 Dart 編程語言編寫的一個跨平臺框架,所以一些語法是基于 Dart 語法來使用的,學習 Flutter 就要先了解 Dart。
1.2 什么是 Dart?
簡單介紹下 Dart 語言。
Dart 是 Google 公司推出的編程語言,屬于應用層編程語言,于 2011 年就已經亮相了。Dart 也是一門面向對象的語言,語法和 Java、C、JavaScript 很像。Dart 里所有的類都可以看成是對象,是單繼承,動態類語言。Dart 可以進行移動應用、Web應用、服務器應用、PC 應用、物聯網應用的開發等等,還在不斷拓展開發平臺,所以可以說 Dart 在各個平臺領域“無所不能”。我們的主角 Flutter 就是基于 Dart 語言編寫的。
1.3 Dart 的特性
接下來看下 Dart 的特性。
- 語法簡單明了,開發速度快、效率高,學習成本低。
- 簡單但是功能強大,可以開發 Web、移動端、PC、服務器端、物聯網等平臺應用。
- 編譯執行速度快,擁有自己的 Dart VM,在移動端和 Web 上擁有高性能。
- 全平臺語言,可移植。Dart 類似于中間件語言,可以編譯成不同平臺的原生代碼,可以很方便地擴展成跨平臺應用語言,如 Android 和 iOS 平臺。
- 語言的結構融合了 Java、C、JavaScrpit 的特點,并結合 React 響應式編程的思維規范進行構建的一個現代化編程語言。
1.4 Dart 的語法特點
- 面向對象的語言,一切數據類型、API 都是對象,都繼承自 Object 類;
- 強類型語言,同時也是動態類型語言。對不確定類型的可以定義成一個動態類型;
- Dart 沒有設置定義訪問域的關鍵字,如果某個變量或者方法、類的名稱以"_"開頭,說明這個變量或者方法、類是私有的,外部不可以調用使用;
- Dart 有入口函數:main(){...};類似于Java的public void main(String[] args){...};
- Dart 吸收了很多現代編程語言的特點,加入了很多便捷的語法支持,可以明顯縮減代碼量和提高可讀性;
- 擁有 Future 和 Streams 使用方式,可以進行類似 RxJava 式的使用。
2 Dart 的關鍵字
好了,說了這么多,接下來該進入正題,我們來學習一些具體知識。首先看下 Dart 的關鍵字(33 個保留字,17 個內置標志符)。
33 個 Dart 保留字:
| assert | break | const | continue | case | catch | class |
| default | else | enum | extends | final | finally | false |
| for | is | in | new | rethrow | return | superdo |
| switch | throw | try | typedef | this | true | var |
| void | while | with | typedef | this |
17 個 Dart 內置標志符:
| abstract | as | covariant | deferred | dynamic | export | external |
| factory | get | implements | import | library | operator | part |
| set | static | typedef |
6 個 Dart2 新增異步功能關鍵字:
| async | async* | await | sync* | yield | yield* |
25 個 Dart 特有關鍵字(和 Java 語言相比):
| as | assert | async | async* | await | const | covariant |
| deferred | dynamic | export | external | factory | get | in |
| is | library | operator | part | rethrow | set | sync* |
| typedef | var | yield | yield* |
3 Dart 的數據類型
我們先看一個官方給的最基礎的 Dart 例子,例如我們新建一個 demo.dart 類:
// 這是程序執行的入口main() { var number = 30; // 定義變量number并進行賦值初始化 printNumber(number); // 調用方法}// 定義方法printNumberprintNumber(num aNumber) { print('The number is $aNumber.'); // 在控制臺打印輸出內容}這個例子涵蓋了 Dart 的一個基礎的語法結構,有入口、有變量聲明、賦值、定義方法、調用方法、傳遞參數、數據類型、變量引用等等。
那么接下來我們看下 Dart 支持的幾種基本數據類型:numbers(num)、String、bool、List 集合、Map 集合、runes(用于在字符串中表示 Unicode 字符)、symbol。
numbers(num)類型是表示數值型的數據類型,包括 int 和 double 類型兩種。num 是 int 和 double 類型的父類。其中 int 整數值一般范圍在 -2^53 和 2^53 之間;double 是 64 位雙精度浮點型數據類型。舉個例子:
void main() { //定義int和double類型 int a = 6; double b = 3.18; print('$a ,$b'); // String轉int int twoInt = int.parse('2'); // String轉double var twoDouble = double.parse('2.2'); print('$twoInt ,$twoDouble'); // int轉String String intToString = 2.toString(); // double轉String,后面需加入保留小數點位數 String doubleToString = 3.23456.toStringAsFixed(2); print('$intToString,$doubleToString'); //自動四舍五入 String fiveString = 2.12832.toStringAsFixed(2); print(fiveString);}輸出結果為:
6 ,3.182 ,2.22,3.232.13大家可以在 DartPad 上進行操作:https://dartpad.dartlang.org
String 類型
大家應該都很熟悉,字符串類型。
- Dart 字符串是 UTF-16 編碼的字符序列,可以使用單引號或者雙引號來創建字符串。
- 可以在字符串中使用表達式,用法是這樣的: ${expression}。
- 可以使用 + 操作符來把多個字符串鏈接為一個,當然也可以不用加號,多個帶引號的字符串挨著寫就可以了。
- 使用三個單引號或者雙引號也可以創建多行字符串。
- 使用 r 前綴可以創建一個原始字符串。
再來看一個例子:
void main() { //單引號和雙引號定義 String singleString = 'A singleString'; String doubleString = "A doubleString"; print('$singleString ,$doubleString');//使用$字符引用變量,使用{}引入表達式 String userS = 'It\'s $singleString'; String userExpression = 'It\'s expression,${singleString.toUpperCase()}'; print('$userS'); print('$userExpression');//使用引號字符串鄰接來拼接或者使用+號連接字符串 String stringLines = 'String ' 'concatenation' " works even over line breaks."; String addString = 'A and ' + 'B'; print('$stringLines'); print('$addString');//使用三個引號(單引號或雙引號)來創建多行字符串 String s3 = '''You can createmulti-line strings like this one.'''; String s33 = """This is also amulti-line string."""; print('$s3'); print('$s33');//使用r為開頭,顯示定義一個原始字符串 String s = r"It is a \n raw string."; print('$s');}輸出結果為:
A singleString ,A doubleStringIt's A singleStringIt's expression,A SINGLESTRINGString concatenation works even over line breaks.A and BYou can createmulti-line strings like this one.This is also amulti-line string.It is a \n raw string.bool 類型
用于定義 true 或 false 的數據類型,很簡單。需要區別注意的是有些寫法在 Dart 里不支持。
var name = 'Tom';if (name) { // JavaScript可以這樣寫,Dart不行 print('He is Tom!');}// JavaScript可以這樣寫,Dart不行if (1) { print('A line Data.');} else { print('A good Data.');}List 集合
Dart 里使用 List 來表示數據集合結構。
void main() { //定義初始化一個集合 var list = [1, 2, 3]; List listData = [5, 6, 7]; print(list.length); print(list[0]); //集合數據賦值 listData[1] = 8; print(listData[1]); //如果在集合前加了const關鍵字,集合數據不可以進行操作 var constantList = const [1, 2, 3]; List datas = List(); datas.add('data1'); datas.addAll(['data2', 'data3', 'data4', 'data5', 'data6']); //輸出第一個元素 print(datas.first); // 獲取最后一個元素 print(datas.last); // 獲取元素的位置 print(datas.indexOf('data1')); // 刪除指定位置元素 print(datas.removeAt(2)); //刪除元素 datas.remove('data1'); //刪除最后一個元素 datas.removeLast(); // 刪除指定范圍元素,含頭不含尾 datas.removeRange(0, 2); //刪除指定條件的元素 datas.removeWhere((item) => item.length > 3); // 刪除所有的元素 datas.clear(); //其他方法可以自己嘗試}Map 集合
Map 集合存儲數據特點就是鍵值對(key-value)形式。key 是唯一的,value 允許重復。看一個實例:
void main() { //定義一個map并賦值 var gifts = { // Keys Values 'first': 'dog', 'second': 'cat', 'fifth': 'orange' }; var nobleGases = { // Keys Values 2: 'a', 10: 'b', 18: 'b', }; //定義一個map并賦值 Map map = Map(); map['first'] = 'a-value'; map['second'] = 'b-value'; map['fifth'] = 'c-value'; Map nobleGasesMap = Map(); nobleGasesMap[2] = 'a-value'; nobleGasesMap[10] = 'b-value'; nobleGasesMap[18] = 'c-value'; //指定鍵值對類型 var nobleGases = new Map<int, String>(); //獲取某個key的value print(map['first']); //獲取map大小 print(map.length); //定義一個不可變的map final constantMap = const { 2: 'a', 10: 'b', 18: 'c', }; //其他API用法和List類似}Runes 類型
表示字符串 Unicode 編碼字符(UTF-32 code points)等。
void main() { //看一個官方例子 var clapping = '\u{1f44f}'; print(clapping); print(clapping.codeUnits); print(clapping.runes.toList()); Runes input = new Runes( '\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}'); print(new String.fromCharCodes(input));}Symbols 類型
使用 Symbol 字面量來獲取標識符的 symbol 對象,也就是在標識符前面添加一個 # 符號。
//看一個官方例子 #radix #bar4 Dart的操作符
看下 Dart 的操作符:
| 一元后綴符(unary postfix) | expr++ ? expr-- ? () ? [] ? . ? ?. |
| 一元前綴符(unary postfix) | -expr ? !expr ? ~expr ? ++expr ? --expr |
| 乘法類型(multiplicative) | * ? / ? % ? ~/ |
| 加法類型(additive) | + ? - |
| 位操作符(shift) | << ? >> |
| 按位與(bitwise AND) | & |
| 按位異或(bitwise XOR) | ^ |
| 按為或(bitwise OR) | \ |
| 比較和類型測試(relational and type test) | >= ? > ? <= ? < ? as ? is ? is! |
| 等價(equality) | == ? != |
| 邏輯與(logical AND) | && |
| 邏輯或(logical OR) | \ |
| 是否是空(if null) | ?? |
| 條件運算符(conditional) | expr1 ? expr2 : expr3 |
| 級聯運算符(cascade) | .. |
| 賦值(assignment) | = ? *= ? /= ? ~/= ? %= ? += ? -= ? <<= ? >>= ? &= ? ^= ? |
這些操作符用法和其他語言的含義和用法大同小異。
5 Dart 的流程控制語句
Dart 流程控制語句也不多,比較簡單。主要有:
- if 和 else
- for 循環
- while 和 do-while 循環
- break 和 continue
- switch 和 case
- assert 斷言(判斷是否相等)
如果其中涉及到使用 try-catch 和 throw,可能會影響一些流程控制的跳轉。
void main() { //if和else if (hasData()) { print("hasData"); } else if (hasString()) { print("hasString"); } else { print("noStringData"); } //for循環 var message = new StringBuffer("Dart is good"); for (var i = 0; i < 6; i++) { message.write(','); } //while while (okString()) { print('ok'); }//do-while do { print('okDo'); } while (!hasData()); //break和continue while (true) { if (noData()) { break; } if (hasData()) { continue; } doSomething(); } //switch和case var command = 'OPEN'; switch (command) { case 'A': executeA(); break; case 'B': executeB(); break; case 'C': executeC(); break; default: executeUnknown(); } //Assert(斷言) assert(string != null); assert(number < 80); assert(urlString.startsWith('https'));}Exceptions 異常捕獲處理。
使用 throw 拋出異常。
throw new FormatException('Expected at least 2 section');也可以拋出其他類型對象。
throw 'no data!';使用 catch 捕獲異常。
try { getData();} on OutOfLlamasException { sendData();} on Exception catch (e) { print('Unknown data Exception: $e');} catch (e) { print('Some Exception really unknown: $e');}使用 rethrow 可以把捕獲的異常給重新拋出。
//給出一個官方例子final foo = '';void misbehave() { try { foo = "You can't change a final variable's value."; } catch (e) { print('misbehave() partially handled ${e.runtimeType}.'); rethrow; // rethrow重新拋出,允許main()里的函數繼續捕獲處理異常 }}void main() { try { misbehave(); } catch (e) { print('main() finished handling ${e.runtimeType}.'); }}Finally 處理,和 Java 里的類似,不管是否出現異常,最終都要執行的方法寫在這里。
try { getData();} catch(e) { print('Error: $e');} finally { //始終執行 sendData();}6 Dart 的類和函數(方法)
類這個概念是面向對象里的,Dart 也依然保留。我們創建對象需要創建類對象,可以使用 new 關鍵字,也可以不使用:
var map=Map();var map2=new Map();調用類方法:
var map=Map(); map.length; //通過 對象.方法 的形式來調用使用方法使用 ?. 來替代 . 可以避免當左邊對象為 null 時拋出異常:
a?.name = 'Tom';關于獲取對象的類型,可以使用 Object 的 runtimeType 屬性來獲取實例的類型。
先看一個實例化對象,并獲取和調用屬性和方法的例子,和 Java 用法基本一致:
class Position { num x; num y; methodPosition(){ ... }}void main() { var pos = new Position(); pos.x = 5;//賦值 print(pos.x);//取值 pos.methodPosition();//調用方法}定義同名構造方法:
class Position { num x; num y; Position(num x, num y) { this.x = x; this.y = y; }}//也可以這樣簡化定義構造方法class Point { num x; num y; Point(this.x, this.y);}注意:Dart 的構造函數不可以繼承,父類的構造函數也不可以繼承。
Dart 也支持抽象函數(抽象類):
abstract class Dog { //可以定義變量和抽象方法 void doSomething(); // 定義抽象方法}class GoodDog extends Dog { void doSomething() { //實現邏輯 }}Dart 的類可以繼承多個類,這個 Dart 的一大特點。Dart 也支持實現多個接口,使用 implements 關鍵字:
class Comparable { final _name; Comparable(this._name); String good1(who) => 'Hello';}class Location { Location(); String good2() => 'World!';}class ImlClass implements Comparable, Location { // ...}Dart 通過 extends 來繼承拓展類,子類可以重寫父類方法,通過 supper 來引用父類方法。
class Product { void open() { //... } // ...}class SmartProduct extends Product { void open() { super.open(); //重寫加入新的邏輯 } // ...}//也可以使用@override注解來表示重寫了父類方法還有其他注解,如可以使用 @proxy 注解來避免警告信息。
Dart 也支持枚舉類型 enum:
enum Color { red, green, blue}//使用時候直接調用Color.blue可以使用 with 關鍵字實現多繼承:
//看一個官方例子class Musician extends Performer with Musical { // ...}class Maestro extends Person with Musical, Aggressive, Demented { Maestro(String maestroName) { name = maestroName; canConduct = true; }}Dart 支持靜態函數使用,使用時候直接類名.函數名即可。
class Position { static num getLongPosition() { return 20; }}void main(){ //直接調用 Position.getLongPosition();}7 Dart 的泛型和限制域
Java 中泛型使用 T 來表示,Dart 里同樣可以使用 T 來表示泛型類型。
abstract class Dog<T> { T getDogByName(String name); setDogByname(String name, T value);}//也可以限制泛型繼承自什么類等操作class Foo<T extends SomeBaseClass> {...}class Extender extends SomeBaseClass {...}void main() { var someBaseClassFoo = new Foo<SomeBaseClass>(); var extenderFoo = new Foo<Extender>(); var foo = new Foo();}Dart 的庫的引入和使用:Dart 使用 import 關鍵字來導入庫和類。
import 'dart:io';import 'package:mylib/mylib.dart';import 'package:utils/utils.dart';//如果兩個導入的庫里的類有重名的,可以使用as關鍵字import 'package:utils2/utils2.dart' as utils2;//也可以只導入庫的一小部分//只導入foo庫import 'package:lib1/lib1.dart' show foo;//除了foo,其他的都導入import 'package:lib2/lib2.dart' hide foo;//延遲載入庫,可以減少APP啟動時間,優化性能import 'package:deferred/hello.dart' deferred as hello;//延遲后,使用的時候使用loadLibrary()來調用//在一個庫上可以多次調用loadLibrary() 函數,只執行載入一次greet() async { await hello.loadLibrary(); hello.printGreeting();}如果我們想自己創建聲明一個庫想被別人引用時候,可以用 library 聲明:
// 聲明庫,名字為abc library abc; // 導入需要用到的相關庫 import 'dart:html'; //編寫邏輯 ... //如果需要的話,可以借助part關鍵字來實現部分需求如果你想聲明某個變量、常量、方法函數不能被外部調用,只需要在名字前加上 _ 下劃線前綴即可。
8 Dart 的異步處理
Dart 支持異步編程操作,例如我們的網絡請求、耗時操作都可以使用。可以使用 async 和 await 關鍵字來進行標識異步操作。
Dart 里也有 Future 和 Stream 對象進行異步操作,非常的強大和方便。
//例如用await來表示這個方法異步的,需要等待完成后才能繼續執行后面的方法await lookUpVersion()//要使用 await,其方法必須帶有 async 關鍵字:checkVersion() async { var version = await lookUpVersion(); if (version == expectedVersion) { //執行操作 } else { //執行操作 }}//我們也可以使用Future來修飾包轉返回類型,這樣我們可以支持數據的后續其他操作Future<String> lookUpVersion() async => '1.6.0';在 await 表達式中,表達式的返回值通常是一個 Future 類型;如果返回的值不是 Future,則 Dart 會自動把該值放到 Future 中返回。
Dart 的基礎語法知識部分就大概這么多,還有很多細節,大家有興趣可以進行深入研究使用方法。
總結
本節課主要是給大家講解 Dart 的基礎語法部分,為后續 Flutter 的開發學習奠定基礎,以期更好地進行深入研究和開發。Dart 的語法比較簡單,和 Java 類似,可以對照著理解,全面詳細的學習用法后,可以為高效開發做好準備。主要注意點和建議如下:
- 建議將例子進行編寫實踐下,使用開發工具輸出下結果加深理解。
- 學習完后,可以進行一個實踐練習,也為學習下一課時作準備。
點擊了解更多《Flutter:從入門到實踐》
注意!!! 為了方便學習和技術交流,特意創建了《Flutter:從入門到實踐》的讀者群,入群方式放在 第 1-3、1-4、1-5 課 文末,歡迎已購本課程的同學入群交流。
第 1-3 課:高效開發環境的搭建
第 1-4 課:Flutter 項目結構及配置文件詳解
第 1-5 課:Flutter 開發規范
第 1-6 課:Flutter Widget 結構概覽
第 1-7 課:編寫第一個 Flutter 應用
第 1-8 課:基礎組件詳解(Text、Image、Button)
第 1-9 課:基礎布局詳解(Scaffold、Container、Center)
第 1-10 課:基礎組件詳解(AppBar、AlertDialog、Icon)
第 1-11 課:基礎組件詳解(TextField、Form 表單)
第 1-12 課:基礎布局詳解(Row、Column、Flex、Expanded、Stack、IndexedStack)
練習篇:仿寫 Instagram 列表
第 2-1 課:列表滾動組件詳解(CustomScrollView、ListView、ScrollView、ExpansionPanel)
第 2-2 課:導航組件詳解(TabBar、NavigationBar、PageView 相關)
第 2-3 課:流式布局組件詳解(Flow、Wrap)
第 2-4 課:表格組件詳解(Table 和 Data Tables)
第 2-5 課:路由詳解
第 2-6 課:生命周期及按鍵監聽
第 2-7 課:HTTP 網絡請求詳解
第 2-8 課:JSON 編解碼的使用
第 2-9 課:WebSocket 的使用
第 2-10 課:文件和圖片讀寫操作詳解
第 2-11 課:手勢和數據庫緩存詳解
第 2-12 課:動畫的使用
第 2-13 課:應用國際化處理
第 2-14 課:Flutter 主題
練習篇:實現一個類似淘寶的商品展示列表頁面
第 3-1 課:自定義 Widget 及方法封裝
第 3-2 課:原生和 Flutter 的交互
第 3-3 課:數據共享與傳遞
第 3-4 課:Dart Pub 使用及 Flutter 插件庫的開發
第 3-5 課:Flutter 調試及 Android 和 iOS 打包
第 3-6 課:延伸——Dart2 的 Web 開發
練習篇:完整實踐——實現一個簡易日記本應用
第 4-1 課:實現一個簡易的音視頻播放器
第 4-2 課:一個權限處理和狀態管理的實踐
結語:Flutter 和 Dart 的總結與展望
閱讀全文: http://gitbook.cn/gitchat/column/5cc01cc115a1a10d8cec9e86
總結
以上是生活随笔為你收集整理的Flutter:从入门到实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 思岚发布新品TOF激光雷达——RPLID
- 下一篇: 51单片机的指令系统(一)