發表日期:2018-09 文章編輯:小燈 瀏覽次數:1861
Google 出品,Dart語言,Flutter Engine引擎,響應式設計模式,原生渲染。
目錄
蘋果的iOS SDKs發布于2008年,谷歌的Android軟件開發工具包發布于2009年,這兩種sdk包是基于不同的編程語言的,分別是Objective-C和Java, 如下是大概的結構圖:
Flutter提供響應式的視圖,提供Dart語言編譯多個平臺的原生代碼,因此可以直接和平臺通信,同時使用Skia圖形引擎來完成圖形、文本、圖像、動畫等繪制,擁有自己獨立的一套圖形系統,不再依賴于原生。避免由JavaScript橋接器引起的性能問題。
Skia:這個是谷歌的一個跨平臺渲染框架,從目前iOS和Anrdroid來看,Skia底層最終都是調用OpenGL繪制。
得益于 Engine 層,Flutter 甚至不使用移動平臺的原生控件, 而是使用自己Engine 來繪制 Widget (Flutter的顯示單元),而 Dart 代碼都是通過 AOT 編譯為平臺的原生代碼,所以 Flutter 可以直接與平臺通信,不需要JS引擎的橋接。同時 Flutter 唯一要求系統提供的是 canvas,以實現UI的繪制。
Dart 還可以編譯成 ARM 和 x86 代碼直接運行在 iOS、Android 設備上。Dart 同時支持 JIT 和 AOT。Just-in-time Compiler(運行時編譯 動態編譯)Ahead-of-time Compiler(運行前編譯 靜態編譯)
如上圖,Flutter 主要分為 Framework 和 Engine,我們基于Framework 開發App,運行在 Engine 上。Engine 是 Flutter 的獨立虛擬機,由它適配和提供跨平臺支持。
在Flutter中,幾乎所有東西都是一個widget - 甚至布局模型都是widget。您在Flutter應用中看到的圖像、圖標和文本都是widget。 甚至你看不到的東西也是widget,例如行(row)、列(column)以及用來排列、約束和對齊這些可見widget的網格。
Widget生命周期
Flutter提供兩種類型的Widget, StatelessWidget 和 StatefulWidget,前者為狀態不可變,后者可以通過setState()改變state來改變更新UI,開發者可以根據自己的實際情況使用
StatefulWidget:
StatelessWidget:
iOS風格Widget
Cupertino (iOS風格) 類型 | 作用特點 |
---|---|
CupertinoNavigationBar | An iOS-style top navigation bar |
CupertinoTabBar | An iOS-style bottom tab bar |
CupertinoActivityIndicator | 一個iOS風格的loading指示器。顯示一個圓形的轉圈菊花 |
CupertinoAlertDialog | 一iOS風格的alert dialog. |
CupertinoButton | iOS風格的button. |
CupertinoDialog | iOS風格的對話框,沒有按鈕 |
CupertinoSlider | An iOS-style slider |
CupertinoSwitch | An iOS-style switch. |
CupertinoPicker | An iOS-style picker control. |
CupertinoPageTransition | Provides an iOS-style page transition animation. |
CupertinoFullscreenDialogTransition | An iOS-style transition used for summoning fullscreen dialogs. |
Material風格Widget
Material類型 | 作用特點 |
---|---|
Scaffold | Material Design布局結構的基本實現。此類提供了用于顯示drawer、snackbar和底部sheet的API。 |
Appbar | 一個Material Design應用程序欄,由工具欄和其他可能的widget(如TabBar和FlexibleSpaceBar)組成。 |
BottomNavigationBar | 底部導航條,可以很容易地在tap之間切換和瀏覽頂級視圖。 |
TabBar | 一個顯示水平選項卡的Material Design widget。 |
TabBarView | 顯示與當前選中的選項卡相對應的頁面視圖。通常和TabBar一起使用。 |
MaterialApp | 一個方便的widget,它封裝了應用程序實現Material Design所需要的一些widget。 |
WidgetsApp | 一個方便的類,它封裝了應用程序通常需要的一些widget。 |
Drawer | 從Scaffold邊緣水平滑動以顯示應用程序中導航鏈接的Material Design面板。 |
Image | Image.assetImage.networkImage.fileImage.memory |
Icon | A Material Design icon. |
RaisedButton | Material Design中的button, 一個凸起的材質矩形按鈕 |
RaisedButton | Material Design中的button, 一個凸起的材質矩形按鈕 |
FloatingActionButton | 一個圓形圖標按鈕,它懸停在內容之上,以展示應用程序中的主要動作。FloatingActionButton通常用于Scaffold.floatingActionButton字段。 |
FlatButton | 一個扁平的Material按鈕 |
IconButton | 一個Material圖標按鈕,點擊時會有水波動畫 |
PopupMenuButton | 當菜單隱藏式,點擊或調用onSelected時顯示一個彈出式菜單列表 |
ButtonBar | 水平排列的按鈕組 |
TextField | 文本輸入框 |
Checkbox | 復選框,允許用戶從一組中選擇多個選項。 |
Radio | 單選框,允許用戶從一組中選擇一個選項。 |
Switch | On/off 用于切換一個單一狀態 |
Slider | 滑塊,允許用戶通過滑動滑塊來從一系列值中選擇。 |
Date & Time Pickers | 日期&時間選擇器 |
SimpleDialog | 簡單對話框可以顯示附加的提示或操作 |
AlertDialog | 一個會中斷用戶操作的對話款,需要用戶確認 |
BottomSheet | BottomSheet是一個從屏幕底部滑起的列表(以顯示更多的內容)。你可以調用showBottomSheet()或showModalBottomSheet彈出 |
SnackBar | 具有可選操作的輕量級消息提示,在屏幕的底部顯示。 |
Card | 一個 Material Design 卡片。擁有一個圓角和陰影 |
ListTile | 一個固定高度的行,通常包含一些文本,以及一個行前或行尾圖標。 |
Divider | 一個邏輯1像素厚的水平分割線,兩邊都有填充 |
Placeholder | 一個繪制了一個盒子的的widget,代表日后有widget將會被添加到該盒子中 |
RefreshIndicator | 內置下拉刷新控件 |
ListView | 可以有多個子 Widget。 |
負責Layout的Widget
Flutter 中擁有需要將近30種內置的 布局Widget,其中常用有 Container、Padding、Center、Flex、Stack、Row、Colum等,下面簡單講解它們的特性和使用。
類型 | 作用特點 |
---|---|
Container | 只有一個子 Widget。默認充滿,包含了padding、margin、constraints、color、width、height、decoration、alignment、transform。 |
Padding | 只有一個子 Widget。只用于設置Padding,常用于嵌套child,給child設置padding。 |
Center | 只有一個子 Widget。只用于居中顯示,常用于嵌套child,給child設置居中。 |
Stack | 可以有多個子 Widget。 子Widget堆疊在一起。 |
Colum | 可以有多個子 Widget。垂直布局。 |
Row | 可以有多個子 Widget。水平布局。 |
Expanded | 只有一個子 Widget。在 Colum 和 Row 中充滿。 |
在iOS系統中,我們使用frame來進行UI布局,同時可以通過addChild和removeChild添加或者移除視圖。
但是在Flutter中,Widget 是不可變的,可以傳入一個函數,該函數返回一個子Widget 給父 Widget。并在該函數中通過一個 bool 值來控制子 Widget 的創建。
children: <Widget>[ new Padding( padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0), child: new RaisedButton( textColor: Colors.black, child: new Text('opacity'), onPressed: () { setState(() { _aniIndex = 0; }); }),), ],
Flutter中有兩種方式來處理touch:
一是直接傳遞一個處理事件的方法給Widget;
或者通過GestureDetector來實現事件監聽與處理。
new Padding(padding: const EdgeInsets.only(left: 10.0, top: 10.0, right: 10.0),child: new GestureDetector(onTapDown: (tapDown) {setState(() {tapEvent = '這是GestureDetector監聽的onTapDown事件';});},onTapUp: (tapUp) {setState(() {tapEvent = '這是GestureDetector監聽的onTapUp事件';});},onTapCancel: () {setState(() {tapEvent = '這是GestureDetector監聽的onTapCancel事件';});},onDoubleTap: () {setState(() {tapEvent = '這是GestureDetector監聽的onDoubleTap事件';});},onLongPress: () {setState(() {tapEvent = '這是GestureDetector監聽的onLongPress事件';});},child: new BorderButton('GestureDetector onTap 分解事件按鈕'),),),
// 創建 AnimationController 對象controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000)); //非線性動畫final CurvedAnimation curvedAnimation = CurvedAnimation(parent: controller,curve: Curves.elasticInOut);// 通過 Tween 對象 創建 Animation 對象animation = Tween(begin: 50.0, end: 200.0).animate(curvedAnimation)//Calls the listener every time the value of the animation changes...addListener(() {// 注意:這句不能少,否則 widget 不會重繪,也就看不到動畫效果setState(() {});})// Calls listener every time the status of the animation changes. ..addStatusListener((status) {if (status == AnimationStatus.completed) {controller.reverse();} else if (status == AnimationStatus.dismissed) {controller.forward();}});// 執行動畫controller.forward();// 做動畫的widgetbody: Center(child: Container(width: animation.value,height: animation.value,decoration: BoxDecoration(color: Colors.redAccent),),),
數據交互
Flutter 是支持原生頁面和 Flutter 頁面混合開發的,但是不支持原生組件在Flutter 中使用,原生端有 MethodChannel 來支持 Flutter 對原生的一些API調用。
flutter -->原生
// flutter Future<Null> _launchPlatformCount() async {final int platformCounter =await _methodChannel.invokeMethod('switchView', _counter);setState(() {_counter = platformCounter;}); }// iOS FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"samples.flutter.io/platform_view" binaryMessenger:controller]; [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {if ([@"switchView" isEqualToString:call.method]) {_flutterResult = result;PlatformViewController* platformViewController =[controller.storyboard instantiateViewControllerWithIdentifier:@"PlatformView"];platformViewController.counter = ((NSNumber*)call.arguments).intValue;platformViewController.delegate = self;UINavigationController* navigationController =[[UINavigationController alloc] initWithRootViewController:platformViewController];navigationController.navigationBar.topItem.title = @"Platform View";[controller presentViewController:navigationController animated:NO completion:nil];} else {result(FlutterMethodNotImplemented);} }];// FlutterResult是一個回調函數
// 把方法聲明為異步方法,通過await關鍵字等待該異步方法執行完成loadData() async { String dataURL = "https://jsonplaceholder.typicode.com/posts"; // http.Response response = await http.get(dataURL); // setState(() { // widgets = json.decode(response.body); // }); Dio dio =new Dio(); Response response = await dio.get(dataURL); setState(() { widgets = response.data; });}
///不帶參數的路由表跳轉 Navigator.pushNamed(context, routeName);///跳轉新頁面并且替換,比如登錄頁跳轉主頁 Navigator.pushReplacementNamed(context, routeName);///跳轉到新的路由,并且關閉給定路由的之前的所有頁面 Navigator.pushNamedAndRemoveUntil(context, '/calendar', ModalRoute.withName('/'));///帶參數的路由跳轉,并且監聽返回 Navigator.push(context, new MaterialPageRoute(builder: (context) => new NotifyPage())).then((res) { ///獲取返回處理 });
可以看到,Navigator 的 push 返回的是一個 Future,這個Future 的作用是在頁面返回時被調用的。也就是你可以通過 Navigator 的 pop 時返回參數,之后在 Future 中可以的監聽中處理頁面的返回結果。
@optionalTypeArgs static Future<T> push<T extends Object>(BuildContext context, Route<T> route) {return Navigator.of(context).push(route); }
Flutter 的優點:
● 熱重載(Hot Reload),利用提供的IDE直接保存代碼并重載,手機或者模擬器立馬就可以看見效果,這一點調試起來很方便。
● Widget的理念,對于Flutter來說,手機應用里的所有組件都是Widget,通過可組合的空間集合、豐富的動畫庫以及分層可擴展的架構實現了富有感染力的靈活界面設計。
● 借助GPU加速的渲染引擎以及高性能本地代碼運行時以達到跨平臺設備的高質量用戶體驗。
Flutter 的不足:
● 開發語言是基于Dart, 對開發者而言,增加了不少學習成本。
● UI布局方面,層次不夠明顯,不那么直接,復雜化了程序的可讀性。
● Flutter是一種新的框架,目前市面上應用和社區不太成熟,而且支持的庫不如ReactNative及原生。
● 目前Dart代碼會AOT編譯到native,不像ReactNative,支持熱更新起來會很難,但從API的結構設計上來看,后期應該很快會實現熱更新。
● 不能支持原生組件在Flutter中顯示,導致很多組件需要重新開發,不如ReactNative靈活。
● 現在還不支持HTML
● bate版 0.58
總之從Flutter的設計理念來看,整體架構都是具有革命性的,相比于其他跨平臺實現了真正意義的跨平臺,各平臺體驗一致,而且讓用戶體驗達到了最優,各種UI庫和組件也在不斷的增加,各種生態系統和社區在不斷的完善,對于以后新的操作系統適配性會更強,如Fuchsia系統,非常值得大家了解和學習,相信不久的將來,會慢慢成熟起來,成為主流開發語言。
日期:2018-10 瀏覽次數:7543
日期:2018-12 瀏覽次數:4626
日期:2018-07 瀏覽次數:5138
日期:2018-12 瀏覽次數:4416
日期:2018-09 瀏覽次數:5777
日期:2018-12 瀏覽次數:10197
日期:2018-11 瀏覽次數:5109
日期:2018-07 瀏覽次數:4859
日期:2018-05 瀏覽次數:5118
日期:2018-12 瀏覽次數:4585
日期:2018-10 瀏覽次數:5392
日期:2018-12 瀏覽次數:6463
日期:2018-11 瀏覽次數:4719
日期:2018-08 瀏覽次數:4869
日期:2018-11 瀏覽次數:12962
日期:2018-09 瀏覽次數:5879
日期:2018-12 瀏覽次數:5097
日期:2018-10 瀏覽次數:4441
日期:2018-11 瀏覽次數:4796
日期:2018-12 瀏覽次數:6323
日期:2018-06 瀏覽次數:4266
日期:2018-08 瀏覽次數:5712
日期:2018-10 瀏覽次數:4701
日期:2018-12 瀏覽次數:4818
日期:2018-07 瀏覽次數:4631
日期:2018-12 瀏覽次數:4803
日期:2018-06 瀏覽次數:4637
日期:2018-11 瀏覽次數:4621
日期:2018-12 瀏覽次數:4552
日期:2018-12 瀏覽次數:5532
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.