Android 和IOS 混合開發,一套程式碼兩處執行-----Flutter
轉載自:https://www.jianshu.com/p/8baa8ed2414d
什麼是Flutter
2018年2月27日,在2018世界移動大會上,Google釋出了Flutter的第一個Beta版本。Flutter是Google用以幫助開發者在Ios和Android兩個平臺開發高質量原生應用的全新移動UI框架,點選檢視Flutter介紹視訊。
其實我第一次聽說Flutter是在收到谷歌開發者公眾號的推送裡,當時讀完了那篇文章覺得Flutter的優點確實比較突出:
- 熱過載(Hot Reload),作為一個菜鳥安卓開發者,能熱過載真的太舒服了,利用Android Studio直接一個ctrl+s就可以儲存並重載,模擬器立馬就可以看見效果,就這一點比原生安卓製作簡直不知道高到哪裡去了。
- 一切皆為Widget的理念,對於Flutter來說,手機應用裡的所有東西都是Widget,通過可組合的空間集合、豐富的動畫庫以及分層課擴充套件的架構實現了富有感染力的靈活介面設計。
- 藉助可移植的GPU加速的渲染引擎以及高效能原生代碼執行時以達到跨平臺裝置的高質量使用者體驗。 這段介紹是直接抄下來的,雖然我並不知道什麼叫可移植的GPU加速的渲染引擎,但是最終結果就是利用Flutter構建的應用在執行效率上會和原生應用差不多。
酷安上有一個Flutter的演示Demo,Flutter Gallery。
如果經常逛酷安的一定會發現這個畫廊的演示Demo的圖示和另一個演示Demo的圖示是一樣的,Google Fuchsia OS Preview
Flutter的核心內容
接下來我想寫一下我自己通過這兩天的接觸對於Flutter的核心內容也就是上面好處的第二點的理解。
一切都是控制元件(Widget)
在Flutter中,每個應用程式都是Widget,這點和其他的應用框架不一樣,Flutter的物件模型是統一的,也就是控制元件。
一個控制元件可以定義:
- 結構元素(比如按鈕或者選單)
- 風格元素(比如字型或者顏色方案)
- 佈局
- 一些業務邏輯
- 等等。。。。
控制元件是基於構圖形成層次結構,每個控制元件巢狀在其中,並從其父代繼承屬性,沒有單獨的“應用程式”物件,只有根控制元件。
您可以通過告知框架用另一個控制元件替換層次結構中的控制元件來響應事件,比如使用者互動,然後框架會對比新的控制元件和舊的控制元件,並有效的更新使用者介面,即更新有變化的控制元件。
也就是說,在Flutter中,一個應用就是有許許多多的Widget組合而成的。
構建第一個Flutter例項
先來介紹一下Flutter裡面的基本空間:
- Text:文字控制元件,在應用中建立各種樣式的文字。
- Row,Column:Flex控制元件,可以建立水平(Row)或垂直(Column)方向的佈局,是基於Web的flexbox的佈局模式設計的。
- Stack:非線性佈局(水平或垂直),控制元件可以堆疊在其他控制元件上,可以使用Positioned控制元件控制Stack相對頂部、右部、底部和左部的位置,是基於Web的absolute定位的佈局模式。
- Container:建立矩形的可視元素,可以用BoxDecoration來設計樣式,比如背景、邊框和陰影,Container也有邊距、填充和大小限制,另外,還可以在三維空間利用矩陣進行變換。
結合例項分析:
import 'package:flutter/material.dart';
class MyAppBar extends StatelessWidget {
MyAppBar({this.title});
final Widget title;
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Container(
height: 56.0,
padding: const EdgeInsets.symmetric(horizontal: 8.0),
decoration: new BoxDecoration(color: Colors.blue[500]),
//new Row意味著該子佈局為水平佈局
child: new Row(
children: <Widget>[
//佈局依次為圖示按鈕,剩餘容器和圖示按鈕,如果把第二個IconButton移動到Expanded前則內容會發生改變
new IconButton(
icon: new Icon(Icons.menu),
tooltip: '導航選單',
onPressed: null
),
//Expanded的作用可以使用剩餘的所有空間。
new Expanded(
child: title
),
new IconButton(
icon: new Icon(Icons.search),
tooltip: '搜尋',
onPressed: null
)
],
),
);
}
}
class MyScaffold extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return new Material(
child: new Column(
children: <Widget>[
new MyAppBar(
title: new Text(
'示例標題',
style: Theme
.of(context)
.primaryTextTheme
.title,
),
),
new Expanded(
child: new Center(
child: new Text('你好世界!'),
),
)
],
),
);
}
}
void main() {
runApp(new MaterialApp(
title: '我的應用',
home: new MyScaffold(),
));
}
其實說真的我第一眼看到這段程式碼的時候,第一想法就是,為什麼會有這麼多括號?但是這不是重點,有點程式設計經驗的都知道要先從main函式看起,這裡的main函式裡面套了一個runApp函式,
runApp函式接受指定的控制元件(Widget),並使其作為控制元件樹(widget tree)的根控制元件。
runApp裡面new了一個MaterialApp物件,然後這個物件有兩個引數,第一個是titile,指明瞭這個控制元件的標題是啥,第二個引數是home,指明瞭這個控制元件的主體是啥。
再深入的看就會發現,home的值是一個new出來的MyScaffold物件,這時我們就可以去檢視MyScaffold這個類的宣告程式碼。
MyScaffold控制元件為子控制元件設定垂直佈局,在垂直頂部放置一個MyAppBar的例項(這個控制元件也是自己建立的),將MyAppBar的Text控制元件作為標題使用,將控制元件作為引數傳遞給其他控制元件非常方便實用的,你可以建立通用的控制元件,以各種方式重複的使用。最後,MyScaffold使用Expanded,用一箇中心文字來填充剩餘的空間。
MyAppBar控制元件建立了一個Container(容器),高度為56裝置無關畫素(device-independent pixels),內部左右填充8畫素(pixels)。在容器內部,MyAppBar為子控制元件設定Row(水平)佈局,中間的title控制元件被設定成Expanded,Expanded的作用是展開Row、Column和Flex的子控制元件,意味它可以使用剩餘的所有空間。
其實上述的分析過程就是一個對控制元件數的一個遍歷,從根控制元件到裡面的子控制元件,Flutter的設計理念就是一切皆為控制元件,元件套組建。雖然上述程式碼不是java,c等主流程式碼,但是理解起來卻並不是非常難懂,上手難度確實不大,值得體驗。