flutter是Google開發的一套全新的跨平臺開源框架。目前flutter已經發布很多很多版本,正在逐步的完善,它的目標其實是和react native一樣的,就是同一份代碼可以同時運行在Android和iOS兩個系統上。如果你同時有react native和flutter開發經驗,你就會發現flutter的很多設計理念和react native是一樣的,react native基於組件開發頁面,flutter則是widget,他們都有自己的生命週期,他們都是自己的屬性或者狀態,所以對於react native開發者來說,flutter開發只不過換了一種Dart語言,換了一批API,當然這些都是表面的理解。因爲react native和flutter有本質的不同,react native渲染的是系統原生控件,flutter則是從頭到尾重寫了一套UI框架,渲染引擎則依靠Skia圖形庫實現。下面就具體說一下H5、react native、flutter這些跨平臺UI框架的方案。
歡迎加入Android開發技術交流QQ羣:653583088,本羣可免費獲取Gradle、RxJava、小程序、Hybrid、移動架構、NDK、React Native、性能優化等技術教程!
H5、react native、flutter
最開始的跨平臺開發的方案就是H5開發,然後基於Android和iOS的webView完全繼承web開發的所有成果,但是由於webview的渲染效率和js的執行性能問題,很難與原生相提並論。然後就到了react native、weex的時代,爲了解決webview性能差的問題,這類框架將最終的渲染工作交還給了系統,拋開react native和weex自身對系統版本的bug,性能問題依然沒有完美的解決,比如加載react native生成的bundle.js的size過大、bundle.js的加載時間過長導致白屏、頁面內手勢滑動導致大量的丟幀問題等等,所以我們在適用reactnative時還是需要大量的優化和維護。這個時候flutter借鑑react native孕育而生,爲什麼是借鑑呢,上面也有提到,其實react native在開發時有很多思想都是相同的。
flutter所使用的語言是Dart,這種語言既支持動態編譯又支持靜態編譯,這也就意味着在JIT模式下我們可以實現熱刷新,就像開發js一樣,編輯完代碼之後,只要保存或者點擊 Hot Reload按鈕,就可以立即更新到設備上,不用重新編譯app。在Flutter中,所有功能都可以通過組合多個Widget來實現,包括對齊方式、按行排列、按列排列、網格排列甚至事件處理等等。Flutter控件主要分爲兩大類,StatelessWidget和StatefulWidget,StatelessWidget用來展示靜態的文本或者圖片,如果控件需要根據外部數據或者用戶操作來改變的話,就需要使用StatefulWidget。State的概念也是來源於Facebook的流行Web框架React,React風格的框架中使用控件樹和各自的狀態來構建界面,當某個控件的狀態發生變化時由框架負責對比前後狀態差異並且採取最小代價來更新渲染結果。
flutter應用
flutter的安裝很簡單,我們只需要一個flutter的sdk就可以,這裏類似於Android裏的sdk,開發flutter的編輯器也有很多選擇,Android studio、intellij、VS code,這裏我選擇的是最輕量的vs code。關於這些配置環境我們可以參考官網,說的很清晰。
當我們用vs code生成一個項目後,項目目錄如下:
其中lib文件夾下的main.dart文件就是我們要開發的dart文件,pubspec.yaml就是項目的配置文件,ios文件夾和android文件夾分別是iOS和Android兩個項目工程
然後我們看一下dart文件:
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; void _incrementCounter() { setState(() { _counter++; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( 'You have pushed the button this many times:', ), Text( '$_counter', style: Theme.of(context).textTheme.display1, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } }
可以看到兩個類MyApp和MyHomePage,從名字我們就可以看出,一個是App的入口,一個是首頁,前者繼承StatelessWidget,後者繼承StatefulWidget,說明MyApp是不需要狀態的,而MyHomePage是需要的,所以它實現了createState方法來生成一個State(不管是StatelessWidget還是StatefulWidget,本身都是不可變的),_MyHomePageState繼承了State<MyHomePage>,重寫了build方法,返回Scaffold,其實Scaffold中的代碼就是展示在頁面中的內容。
最後附上flutter的架構圖:
歡迎加入Android開發技術交流QQ羣:653583088,本羣可免費獲取Gradle、RxJava、小程序、Hybrid、移動架構、NDK、React Native、性能優化等技術教程!