簡介:近兩年Flutter的熱度不斷提升,無論在阿里還是外部公司,參與Flutter生態建設的人越來越多。Flutter作為跨端的UI框架,未來也有很大的可能像Rax一樣作為集團內行銷活動頁面搭建的DSL。所以目前學習Flutter,參與Flutter生態建設是一件時髦且有價值的事情。
Flutter是谷歌的移動UI框架,可以快速在iOS和Android上構建高品質的原生使用者介面。Flutter可以與現有的程式碼一起工作。在全世界,Flutter正在被越來越多的開發者和組織使用,並且Flutter是完全免費、開源的。簡單來說,Flutter是一款移動應用程式SDK,包含框架、控制元件和一些工具,可以用一套程式碼同時構建Android和iOS應用,並且效能可以達到原生應用一樣的效能。Flutter簡介
Flutter開發可以在macOS,Linux或Windows上完成。雖然您可以在Flutter工具鏈中使用任何編輯器,但IntelliJ IDEA,Android Studio和Visual Studio Code的IDE外掛可以簡化開發工作。
▐ Android Studio (為Flutter提供完整的IDE體驗)
建立應用
執行應用程式
定位到Android Studio 工具列:
▐ VS Code(輕量級編輯器,支援Flutter執行和偵錯)
建立應用
執行應用程式
▐ Terminal + 編輯器
建立應用
使用 flutter create 命令建立一個project:
$ flutter create myapp
$ cd myapp
執行應用程式
$ flutter devices
執行 flutter run 命令來執行應用程式:
$ flutter run
如果一切正常, 您應該在您的裝置或模擬器上會看到啟動的應用程式:
## 專案結構
┬
└ projectname
┬
├ android - Android部分的工程檔案
├ build - 專案的構建輸出目錄
├ ios - iOS部分的工程檔案
├ lib - 專案中的Dart原始檔
┬
└ src - 包含其他原始檔
└ main.dart - 自動生成的專案入口檔案,類似RN的index.js檔案
├ test - 測試相關檔案
└ pubspec.yaml - 專案依賴組態檔類似於RN的 package.json
Flutter 使用 Dart 構建系統和 Pub 包管理器來處理依賴。這些工具將Android 和 iOS native 包裝應用程式的構建委派給相應的構建系統。
dependencies:
flutter:
sdk: flutter
google_sign_in: ^3.0.3
在Flutter中,雖然在Flutter專案中的Android資料夾下有Gradle檔案,但只有在新增平臺相關所需的依賴關係時才使用這些檔案。否則,應該使用pubspec.yaml來宣告用於Flutter的外部依賴項。
iOS也是一樣,如果你的 Flutter 工程中的 iOS 資料夾中有 Podfile,請僅在新增iOS平臺相關的依賴時使用它。否則,應該使用pubspec.yaml來宣告用於Flutter的外部依賴項。
雖然Android將resources 和 assets 區別對待,但在Flutter中它們都會被作為assets處理, 所有存在於Android上res/drawable- *資料夾中的資源都放在Flutter的assets資料夾中。
與Android類似,iOS 同樣將 images 和 assets 作為不同的東西,而 Flutter 中只有 assets。被放到 iOS 中 Images.xcasset 資料夾下的資源在 Flutter 中被放到了 assets 資料夾中。
在Flutter中assets可以是任意型別的檔案,而不僅僅是圖片。例如,你可以把 json 檔案放置到 my-assets 資料夾中。
my-assets/data.json
記得在 pubspec.yaml 檔案中宣告 assets:
assets:
- my-assets/data.json
然後在程式碼中我們可以通過 AssetBundle 來存取它:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
Future<String> loadAsset() async {
return await rootBundle.loadString('my-assets/data.json');
}
對於圖片,Flutter 像 iOS 一樣,遵循了一個簡單的基於畫素密度的格式。Image assets 可能是 1.0x 2.0x 3.0x 或是其他的任何倍數。這個 devicePixelRatio 表示了物理畫素到單個邏輯畫素的比率。
Android不同畫素密度的圖片和Flutter的畫素比率的對應關係
ldpi 0.75x
mdpi 1.0x
hdpi 1.5x
xhdpi 2.0x
xxhdpi 3.0x
xxxhdpi 4.0x
舉個例子,要把一個名為 my_icon.png 的圖片放到 Flutter 工程中,你可能想要把它放到images資料夾中。把圖片(1.0x)放置到 images 資料夾中,並把其它解析度的圖片放在對應的子資料夾中,並接上合適的比例係數,就像這樣:
images/my_icon.png // Base: 1.0x image
images/2.0x/my_icon.png // 2.0x image
images/3.0x/my_icon.png // 3.0x image
接下來就可以在pubspec.yaml檔案中這樣宣告這個圖片資源:
assets:
- images/my_icon.png
現在,我們就可以藉助AssetImage來存取它了。
return AssetImage("images/a_dot_burr.jpeg");
也可通過 Image widget 直接使用:
@override
Widget build(BuildContext context) {
return Image.asset("images/my_image.png");
}
如何歸檔strings資源,以及如何處理不同語言?
不像 iOS 擁有一個 Localizable.strings 檔案,Flutter目前沒有專門的字串資源系統。目前,最佳做法是將strings資源作為靜態欄位儲存在類中。例如:
class Strings {
static String welcomeMessage = "Welcome To Flutter";
}
然後像如下方式來存取它:
Text(Strings.welcomeMessage)
預設情況下,Flutter 只支援美式英語字串。如果你要支援其他語言,請引入 flutter_localizations 包。你可能也要引入 intl 包來支援其他的 i10n 機制,比如日期/時間格式化。
dependencies:
# ...
flutter_localizations:
sdk: flutter
intl: "^0.15.6"
要使用 flutter_localizations 包,還需要在 app widget 中指定 localizationsDelegates 和 supportedLocales。
import'package:flutter_localizations/flutter_localizations.dart';
MaterialApp(
localizationsDelegates: [
// Add app-specific localization delegate[s] here
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'), // English
const Locale('he', 'IL'), // Hebrew
// ... other locales the app supports
],
// ...
)
這些代理包括了實際的在地化值,並且 supportedLocales 定義了 App 支援哪些地區。上面的例子使用了一個 MaterialApp ,所以它既有 GlobalWidgetsLocalizations 用於基礎 widgets,也有 MaterialWidgetsLocalizations 用於 Material wigets 的在地化。如果你使用 WidgetsApp ,則無需包括後者。注意,這兩個代理雖然包括了「預設」值,但如果你想讓你的 App 在地化,你仍需要提供一或多個代理作為你的 App 在地化副本。
當初始化時,WidgetsApp 或 MaterialApp 會使用你指定的代理為你建立一個 Localizations widget。Localizations widget 可以隨時從當前上下文中存取裝置的地點,或者使用 Window.locale。
要存取在地化檔案,使用 Localizations.of() 方法來存取提供代理的特定在地化類。如需翻譯,使用 intl_translation 包來取出翻譯副本到 arb 檔案中。把它們引入 App 中,並用 intl 來使用它們。
更多 Flutter 中國際化和在地化的細節,請存取 internationalization guide ,裡面有不使用 intl 包的範例程式碼。
在 Flutter 中一切皆是 元件,僅僅 Widget 的子類和間接子類就有350多個,如此多的元件到底如果學習,真的需要學習 350 多個元件?經濟學中有一個著名的 二八定律 ,而我們學習 Flutter 也適用於二八定律,大部分元件是平時很少用到的,因此作為初學者,只需學習那 20% 常用的元件即可。
RenderObjectWidget及其子類共有89個:
ProxyWidget及其子類共有34個:
StatelessWidget及其子類共有89個:
StatefulWidget的子類最多,高達141個
▐ 元件樹
Flutter 建立App的時候,所有的元件最後會生成一個元件樹,例如如下程式碼:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
),
home: Scaffold(
body: Text('Hello world!'),
),
);
}
}
main 函數是應用程式開始的地方,執行 MyApp 元件。生成的元件樹如下:
讓 Text 元件居中,修改如下:
Scaffold(
body: Center(
child: Text('Hello world!'),
),
)
給應用程式新增 AppBar:
Scaffold(
appBar: AppBar(),
body: Center(
child: Text('Hello world!'),
),
)
▐ StatefulWidget vs StatelessWidget
Flutter 中元件分為 無狀態元件(StatelessWidget) 和 有狀態元件(StatefulWidget)兩種。它們唯一的區別就是執行時 重新載入 元件的方式不同,StatelessWidget 元件重新載入時重新建立當前元件的範例,而StatefulWidget元件重新載入時不會重新建立範例,而是重新執行 build 函數。
StatelessWidget 元件建立的方式:
class StatelessWidgetDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container();
}
}
build 函數返回當前元件,此元件一旦建立將不可改變,build 函數只能執行一次。如果想重新繪製此元件,只能重新建立此元件新的範例。
StatefulWidget 元件建立的方式:
class StatefulWidgetDemo extends StatefulWidget {
@override
_StatefulWidgetDemoState createState() => _StatefulWidgetDemoState();
}
class _StatefulWidgetDemoState extends State<StatefulWidgetDemo> {
@override
Widget build(BuildContext context) {
return Container();
}
}
StatefulWidget 元件的建立方式和 StatelessWidget 不同,State<> 中的 build 函數返回當前元件,有狀態的元件可以在其生命週期內多次重繪,即多次呼叫 build 函數,而不是建立一個新的範例。
StatefulWidget 元件重繪需要呼叫 setstate 方法,setstate 會使其自身及其子元件重繪,所以儘量封裝 StatefulWidget 元件,避免無效的重建和重繪,影響效能。
快速書寫小技巧:在 Android Studio 和 VS Code 中 輸入 stl 然後點選回車,可以快速建立 StatelessWidget 元件,同理輸入 stf 點選回車,可以快速建立 StatefulWidget 元件,這是編輯器 Live Templates 的功能。
▐ Material vs Cupertino
Flutter 中包含兩套風格的元件,分別是 Material 和 Cupertino ,Cupertino 是 iOS風格的元件,命名都帶 Cupertino 字首,比如 CupertinoSlider 、 CupertinoDatePicker 等, Material Design 是由 Google 推出,旨在為手機、平板電腦、桌上型電腦和「其他平臺」提供更一致、更廣泛的「外觀和感覺」。
Flutter 使用一套程式碼在不同的平臺上表現一致,它不會根據不同的平臺繪製不同的外形,比如使用 AlertDialog 彈出警告框,不管在 Android 上,還是在 iOS上效果是一樣。
但有一些功能 Flutter 區分平臺,比如 ListView 滑動到底部時繼續滑動,Android 底部會出現淡藍色(預設情況下)拱形,而 iOS 上則沒有,這是因為 Flutter 在封裝此元件時在程式碼中區分了平臺,所以在檢視 Flutter 原始碼到過程中會經常看到根據不同的平臺做不同處理的情況。
Flutter學習成本主要還是在元件的熟悉上,能數量常用元件就可以上手專案了,至於其他的控制元件只需大概瀏覽一下,做專案的時候遇到一些功能能夠想起 Flutter 已經提供了此元件就可以了。
Flutter 直播第一期預告
關注「淘系技術」微信公眾號,一個有溫度有內容的技術社群~
原文連結:https://developer.aliyun.com/article/771969?
版權宣告:本文內容由阿里雲實名註冊使用者自發貢獻,版權歸原作者所有,阿里雲開發者社群不擁有其著作權,亦不承擔相應法律責任。具體規則請檢視《阿里雲開發者社群使用者服務協定》和《阿里雲開發者社群智慧財產權保護指引》。如果您發現本社群中有涉嫌抄襲的內容,填寫侵權投訴表單進行舉報,一經查實,本社群將立刻刪除涉嫌侵權內容。