Flutter 的 2019 很是精彩:
聲網(wǎng)開(kāi)源了 Flutter 實(shí)時(shí)音視頻插件 Agora Flutter SDK;
閑魚(yú)開(kāi)源了 Flutter 應(yīng)用框架 Fish Redux;
今日頭條即將開(kāi)源能讓 Flutter 真正支持 View 級(jí)別混合開(kāi)發(fā)的方案……
從 2016 年項(xiàng)目啟動(dòng),到在次年的 Google I/O 大會(huì)上首次公開(kāi)亮相,再到 2018 年底憑借
1.0 正式版
的推出首頁(yè)“屠版”,F(xiàn)lutter 幾經(jīng)周折,終是再度回歸業(yè)界關(guān)注的焦點(diǎn)。作為 Google 推出的移動(dòng) UI 框架,F(xiàn)lutter 可以快速在 iOS 和 Android 上構(gòu)建高質(zhì)量的原生用戶界面;可以與現(xiàn)有的代碼一起工作。在全世界,F(xiàn)lutter 正在被越來(lái)越多的開(kāi)發(fā)者和組織使用,同時(shí)其還是完全免費(fèi)、開(kāi)源的。那么較之其他主流框架,其“個(gè)人魅力”何在?而秉承“一切皆為組件”這一核心理念的 Flutter 又有哪些令人驚艷的常用組件呢?
接下來(lái),我們將帶著問(wèn)題,在捷智云視頻會(huì)議系統(tǒng)聯(lián)合創(chuàng)始人亢少軍的《Flutter 技術(shù)入門(mén)與實(shí)戰(zhàn)》一書(shū)中尋找答案。
不斷迭代的跨平臺(tái)技術(shù)
如今,主流的移動(dòng)開(kāi)發(fā)平臺(tái)當(dāng)屬 Android 和 iOS,每個(gè)平臺(tái)上的開(kāi)發(fā)技術(shù)不太一樣,針對(duì)每個(gè)平臺(tái)開(kāi)發(fā)應(yīng)用需要特定的人員,但這樣一來(lái)開(kāi)發(fā)效率低下,因而需要進(jìn)行跨平臺(tái)開(kāi)發(fā)。跨平臺(tái)技術(shù)從最開(kāi)始的 Hybrid 混合開(kāi)發(fā)技術(shù),到 React Native 的橋接技術(shù),一直在演進(jìn)。
Hybrid 開(kāi)發(fā)主要依賴于 WebView。但 WebView 是一個(gè)重量級(jí)的控件,很容易產(chǎn)生內(nèi)存問(wèn)題,而且復(fù)雜的 UI 在 WebView 上顯示的性能不好。
而 React Native 技術(shù)則拋開(kāi)了 WebView,利用 JavaScript Core 來(lái)做橋接,將 JavaScript 調(diào)用轉(zhuǎn)為 Native 調(diào)用。React Native 最終會(huì)生成對(duì)應(yīng)的自定義原生控件。這種策略將框架本身和 App 開(kāi)發(fā)者綁在系統(tǒng)的控件上,不僅框架本身需要處理大量平臺(tái)相關(guān)的邏輯,隨著系統(tǒng)版本變化和 API 的變化,開(kāi)發(fā)者可能也需要處理不同平臺(tái)的差異,甚至有些特性只能在部分平臺(tái)上實(shí)現(xiàn),這樣使得跨平臺(tái)特性大打折扣。
Flutter 是最新的跨平臺(tái)開(kāi)發(fā)技術(shù),可以橫跨 Android、iOS、MacOS、Windows、Linux 等多個(gè)系統(tǒng)。其采用了更為徹底的跨平臺(tái)方案,即自己實(shí)現(xiàn)了一套 UI 框架,然后直接在 GPU 上渲染 UI 頁(yè)面。
一切皆為組件
Flutter 里有一個(gè)非常重要的核心理念:一切皆為組件(Widget),F(xiàn)lutter 所有的元素皆由組件組成。比如:一個(gè)布局元素、一個(gè)動(dòng)畫(huà)、一個(gè)裝飾效果等。
組件是 Flutter 應(yīng)用程序用戶界面的基本構(gòu)建塊。不僅按鈕、輸入框、卡片、列表這些內(nèi)容可作為 Widget,甚至將布局方式、動(dòng)畫(huà)處理都視為 Widget。所以 Flutter 具有一致的統(tǒng)一對(duì)象模型:Widget。
Widget 具有豐富的屬性及方法,屬性通常用來(lái)改變組件的狀態(tài)(顏色、大小等)及回調(diào)方法的處理(單擊事件回調(diào)、手勢(shì)事件回調(diào)等)。方法主要是提供一些組件的功能擴(kuò)展。
復(fù)雜的功能界面通常都是由一個(gè)一個(gè)簡(jiǎn)單功能的組件組裝完成的。有的組件負(fù)責(zé)布局,有的負(fù)責(zé)定位,有的負(fù)責(zé)調(diào)整大小,有的負(fù)責(zé)漸變處理,等等。這種嵌套組合的方式帶來(lái)的最大好處就是解耦。
下面將列舉并講解部分開(kāi)發(fā)中用得最為頻繁的組件。
容器組件
容器組件(Container)包含一個(gè)子 Widget,自身具備如 alignment、 padding 等基礎(chǔ)屬性,方便布局過(guò)程中擺放 child。Container 組件常用屬性見(jiàn)下表:

提示:padding 與 margin 的不同之處在于,padding 是包含在 Content 內(nèi),而 margin 則是外部邊界。設(shè)置點(diǎn)擊事件的話,padding 區(qū)域會(huì)響應(yīng),而 margin 區(qū)域不會(huì)響應(yīng)。
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '容器組件示例',
home: Scaffold(
appBar: AppBar(
title: Text('容器組件示例'),
),
body: Center(
//添加容器
child: Container(
width: 200.0,
height: 200.0,
//添加邊框裝飾效果
decoration: BoxDecoration(
color: Colors.white,
//設(shè)置上下左右四個(gè)邊框樣式
border: new Border.all(
color: Colors.grey, //邊框顏色
width: 8.0, //邊框粗細(xì)
),
borderRadius:
const BorderRadius.all(const Radius.circular(8.0)), //邊框的弧度
),
child: Text(
'Flutter',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 28.0),
),
),
),
),
);
}
}
上述示例代碼視圖展現(xiàn)大致如下圖所示:

圖片組件
圖片組件(Image)是顯示圖像的組件,Image 組件有多種構(gòu)造函數(shù):
new Image:從 ImageProvider 獲取圖像
new Image.asset:加載資源圖片
new Image.file:加載本地圖片文件
new Image.network:加載網(wǎng)絡(luò)圖片
new Image.memory:加載 Uint8List 資源圖片
Image 組件常見(jiàn)屬性見(jiàn)下表:

Image 組件屬性及描述
文本組件
文本組件(text)負(fù)責(zé)顯示文本和定義顯示樣式,常用屬性見(jiàn)下表。

Text 組件屬性及描述
接下來(lái)我們通過(guò)創(chuàng)建多個(gè)文本組件來(lái)展示不同的文本樣式。比如不同的顏色、不同的字號(hào)、不同的線形等,完整示例代碼如下:
import 'package:flutter/material.dart';
class ContainerDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('文本組件'),
),
body: new Column(
children: <Widget>[
new Text(
'紅色+黑色刪除線+25號(hào)',
style: new TextStyle(
color: const Color(0xffff0000),
decoration: TextDecoration.lineThrough,
decorationColor: const Color(0xff000000),
fontSize: 25.0,
),
),
new Text(
'橙色+下劃線+24號(hào)',
style: new TextStyle(
color: const Color(0xffff9900),
decoration: TextDecoration.underline,
fontSize: 24.0,
),
),
new Text(
'虛線上劃線+23號(hào)+傾斜',
style: new TextStyle(
decoration: TextDecoration.overline,
decorationStyle: TextDecorationStyle.dashed,
fontSize: 23.0,
fontStyle: FontStyle.italic,
),
),
new Text(
'24號(hào)+加粗',
style: new TextStyle(
fontSize: 23.0,
fontStyle: FontStyle.italic,
fontWeight: FontWeight.bold,
letterSpacing: 6.0,
),
),
],
),
);
}
}
void main() {
runApp(
new MaterialApp(
title: 'Text demo',
home: new ContainerDemo(),
)
);
}
上述示例代碼視圖展現(xiàn)大致如下圖:
