Flutter 食髓知味

移動開發演變

  1. 原生開發

   早期針對各平臺(操做系統差別),使用相應平臺支持的開發語言,開發應用。就 ios 和 android 兩大陣營來說,須要兩套代碼來實現一款應用,生產效率相對較低。前端

  1. 混合開發(Hybrid)

   H5 技術的出現,爲 web 運行在原生應用中提供了更好的支持。webview + jsBridge 讓 web 開發者也可以開發原生應用,而且一套代碼適配兩端。vue

  1. 原生渲染

   前端框架羣雄逐鹿,React 社區推出了 React-Native ,經過 JS 控制原生控件,一樣作到了適配兩端,但性能依然是瓶頸,JS 語言成爲了限制所在。android

  1. 自制 UI 引擎

   吸取其餘框架所長,自制 UI 引擎。Flutter 使用 dart 語言開發,靜態類型,編譯型語言,AOT 讓運行時速度更快。既不使用 webview 也不使用操做系統原生控件, 自制 UI 引擎,能夠保證在 android 和 ios 的一致性。ios

Flutter UI

繪圖原理

   一切前端編碼都是 GUI 編程,即針對於操做系統硬件繪圖能力的應用。git

UI (用戶界面)
        /\
        ||
        GPU
        /\
        ||
        CPU
複製代碼

   用戶界面由大量的顯像單元組成,每一個像素點的顏色構成了整個視圖界面。咱們經過編碼來控制像素點色號,從而控制視圖成像。編碼發出系統指令,CPU 首先根據指令計算內容數據,再交由 GPU 生成每一個像素點的色彩數據,最終輸出給顯像單元呈色。github

   flutter 在原生應用平臺之上構建了一套完整的 UI 系統,調用 OpenGL 庫來間接調用操做系統 API。從而實現跨平臺操做,而且保證了原生的渲染性能。web

Flutter
      ||
      \/
    OpenGL
      ||
      \/
    OS API
複製代碼

Flutter UI 系統

   有 web 開發經驗,使用過諸如 React, vue 等框架的同窗,理解 Flutter 系統會更加容易些。吸取現代前端系統架構,採用組件化及聲明式,Flutter 也是這一思想的踐行者。算法

Widget                  Component
      ||                       ||
      \/                       \/
    Element                VirtualDOM
      ||                       ||
      \/                       \/
  RenderObject                dom
複製代碼

   一樣以組件爲 UI 構成的最小單元,將視圖單元抽象成相應的數據結構單元,在交互致使的狀態變化時使用優化後的對比算法來獲取最小修改集合,經過 batchUpdate 來更新視圖, 總體思想與 web 前端框架一模一樣。編程

   其中 Widget (同比組件) 分爲 StatelessWidget 和 StatefulWidget 兩類,可類比無狀態組件和有狀態組件。緩存

Dart 與 Flutter

  1. Dart 單線程模型

使用 Event Loop 事件調度模型,Dart 與 JS 一樣選用單線程循環執行任務。

  1. final 和 const

爲何 dart 要支持兩種不可變量聲明方式,final 和 const 到底有什麼不同的?

var count = 10;
final Num = count;  // final 只能賦值一次
const Num1 = 10; // const賦值必須是編譯時常量
複製代碼

const 特殊之處在於,它所聲明的變量值必須是運行時常量。

  1. 定義必傳參數
const Scrollbar({Key key, @required Widget child})
複製代碼

經過 @required 修飾的命名參數爲必傳參數,調用時不傳會致使編譯報錯。

  1. 初始化列表

dart 支持了在建立實例時,初始化實例對象成員的能力,被稱爲 初始化列表

import 'dart:math';

class Point {
  final int x;
  final int y;
  final num distance;

  // 在 : 後進行初始化列表操做
  Person(x, y):
    x = x,
    y = y,
    distance = sqrt(x * x + y * y);
}

void main() {
  final i = new Point(2, 3);
  print(i.distance)
}
複製代碼
  1. Widget build

widget 須要實現 build,做爲 UI 輸出函數。

Widget build(BuildContext context);
複製代碼

context 爲當前結點的上下文,指代組件實例對象。

  1. 建立 cacheable 對象

若是你想建立緩存對象,能夠考慮使用工廠構造函數。

class Logger {
  final String name;
  bool mute = false;
  static final Map<String, Logger> _cache = {};

  factory Logger(String name) {
    // 工廠構造函數中不能使用 this
    if (_cache.contains(name)) {
      // 返回緩存對象
      return _cache[name]
    } else {
      // 經過命名構造函數建立 Logger 實例
      final Logger log = Logger.internal(name);
      _cache[name] = log;
      return log;
    }
  }

  Logger.internal(this.name);

  void log (String msg) {
    if (!mute) print(msg);
  }
}

var logger = Logger('UI');
logger.log('clicked');
複製代碼

使用體驗

優勢

  1. 類型系統帶來的穩定性

   出身 web 開發,深切感覺了 JS 語言編寫應用的不穩定性,其根本緣由是 JS 爲弱類型語言,無 AOT 機制,即使引入了 Typescript 仍是沒法完全解決這一問題,由於不少前端開發人員並無意識到面向接口編程的利好。
   在 Flutter 中並不存在問題,Flutter 使用的 dart 語言自帶類型系統,支持 JIT 的同時也支持 AOT,類型爲必選項,而且若是類型錯誤是沒法編譯經過的。
   因而在咱們類型編寫無誤的狀況下,編譯階段能夠幫助咱們檢驗編碼中的錯誤, 杜絕取值隱患,鮮有可能再出現相似以下錯誤。

  1. 優質的用戶使用體驗

   在 Flutter 以前,也有 RN ,Weex 等跨平臺移動端框架,但因爲其設計是在原生系統之上又構建了一個統一調度層,所以在性能表現上有所降低,尤爲在動畫渲染中須要時刻同步原生系統,不足之處更爲明顯。
   Flutter 使用了自制 UI 引擎,在底層兼容了平臺差別,取代了 Android 與 Ios 原生渲染引擎,暴露給開發者的一致性的 API,這一點既保證了跨平臺兼容,也解決了性能問題。

缺點

  1. widget 嵌套地獄

   Flutter 在語法層面也並不是盡善盡美,經過組合來構建 UI 的常見模式廣爲接受,但其語法設定顯得十分累贅。

   簡單的樣式描述,就須要許多 widget 進行組合,致使一小塊的 UI 結構可能就須要盡百行的代碼來繪製,這對於應用的可讀,後續維護,業務擴展都是極其不利的。
   或許能夠參考形如 React 中 JSX 語法,支持如 DartX,經過 XML 和 style 的組合,來簡化結構,加強可讀性。這一點在社區也有諸多共鳴

相關文章
相關標籤/搜索