Flutter2 入門知識

RainDou發表於2019-09-12

本文對應github地址Flutter2,如果由於github調整導致資源找不到,請訪問github

為什麼Flutter選擇了Dart語言(不用js)

  1. Dart 的效能更好。JIT模式速度與JavaScript持平,AOT模式效能好於JavaScript。
  2. 縮短開發週期。Debug時預設JIT,且支援熱過載。
  3. Native Binding。JavaScript在Android上Native Binding可以很好地實現,但iOS上的 JavaScriptCore不可以,Dart的 Native Binding可以很好地通過 Dart Lib實現。
  4. Fuchsia OS。Fuchsia OS內建的應用瀏覽器就是使用 Dart語言作為 App的開發語言。而且實際上,Flutter是 Fuchisa OS的應用框架概念上的一個子集。(Flutter原始碼和編譯工具鏈也充斥了大量的 Fuchsia巨集)
  5. Dart是型別安全的語言,擁有完善的包管理和諸多特性。Google召集了如此多個程式語言界的設計專家開發出這樣一門語言,旨在取代 JavaScript,所以 Fuchsia OS內建了 Dart。Dart可以作為 embedded lib嵌入應用,而不用只能隨著系統升級才能獲得更新,這也是優勢之一。

Skia是什麼

  • Skia是一個 2D的繪圖引擎庫,其前身是一個向量繪圖軟體,Chrome和 Android均採用 Skia作為繪圖引擎。
  • Skia提供了非常友好的 API,並且在圖形轉換、文字渲染、點陣圖渲染方面都提供了友好、高效的表現。
  • Skia是跨平臺的,所以可以被嵌入到 Flutter的 iOS SDK中,而不用去研究 iOS閉源的 Core Graphics / Core Animation。
  • Android自帶了 Skia,所以 Flutter Android SDK要比 iOS SDK小很多。

Flutter Framework

  • 這是一個純 Dart實現的 SDK,類似於 React在 JavaScript中的作用,它實現了一套基礎庫, 用於處理動畫、繪圖和手勢。
  • 其繪圖封裝了一套 UI庫(dart:ui),有 Material 和Cupertino兩種視覺風格。我們在使用 Flutter寫 App的時候,直接匯入這個庫即可使用元件等功能

Flutter Engine

  • 這是一個純 C++實現的 SDK,其中囊括了 Skia引擎、Dart執行時、文字排版引擎等.
  • 它可以以 JIT 或 AOT的模式執行 Dart程式碼。
  • 在程式碼呼叫 dart:ui庫時,提供 dart:ui庫中 Native Binding 實現。
  • 他還控制著 VSync訊號的傳遞、GPU資料的填充等,並且還負責把客戶端的事件傳遞到執行時中的程式碼

Flutter命名規範

  • 檔名: 小寫+下劃線
  • 型別名(類名、函式型別名):大寫開頭駝峰
  • 變數名(包含const final 常量):使用小寫開頭駝峰
  • const可以使用大寫+下劃線的方式
  • 方法名:使用小寫開頭駝峰
  • 導包as後的名稱為小寫+下劃線
  • 不要用匈牙利命名法中的kXXXX 這樣的命名方式,應該去掉k
  • 超過兩位的英文縮寫一律按該單詞為普通小寫單詞處理,使用小寫

一些關鍵字

  1. extends(繼承關鍵字)
  • Flutter中的繼承是單繼承
  • 建構函式不能繼承
  • 子類重寫超類的方法,要用@override
  • 子類呼叫超類的方法,要用super
  1. Scaffold(實現了基本的 Material Design 佈局結構)
  • appBar: 介面頂部導航條
  • body: 當前介面所顯示的主要內容 Widget
  • floatingActionButton: Material設計中定義的一個功能按鈕
  • persistentFooterButtons: 固定在下方顯示的按鈕,如對話方塊下方的確定、取消按鈕
  • drawer: 抽屜選單控制元件
  • backgroundColor: 背景色,預設是 ThemeData.scaffoldBackgroundColor 的值
  • bottomNavigationBar: 顯示在頁面底部的導航欄
  • resizeToAvoidBottomPadding: 預設true,控制body是否重新佈局來避免底部被覆蓋了,如當鍵盤顯示的時候,重新佈局避免被鍵盤蓋住內容

package匯入要求

  • 導包最好按如下順序排序(可以空行分隔)
  1. dart sdk內的庫
  2. flutter內的庫
  3. 第三方庫
  4. 自己的庫
  5. 相對路徑引用

一些語法特性

  • => expr 等同於{ return expr; } 如果無返回值省略return

    // forEach
    list4.forEach((itemValue) => print(itemValue));
    list4.forEach((itemValue) {
      print(itemValue);
    });
    複製程式碼
  • .. 級聯符號 在同一物件上進行一系列操作

    class StarInfo {
      String name;
      printInfo() {
        print("${name}");
      }
    }
    
    // 常規
    var starInfo1 = StarInfo();
    starInfo1.name = "Li Xiaolong";
    starInfo1.printInfo();
    // 級聯
    var starInfo2 = StarInfo();
    starInfo2
      ..name = "Li XiaoLong"
      ..printInfo(); // 結尾才有分號
    複製程式碼
  • Dart 的類不支援public、private這樣限制詞。_下劃線代表私有。

    class TestGetSet {
      // 私有
      String _userName; 
      String _nickName;
    
      String get userName {
        return _userName ?? _nickName;
      }
      set userName(String newName) {
        _userName = newName;
      }
      set nickName(String newName) {
        _nickName = newName;
      }
    }
    
    // 使用
    var testGetSet = new TestGetSet();
    testGetSet.nickName = "LiXiaolong";
    print("${testGetSet.userName}"); // LiXiaolong
    複製程式碼
  • 運算子(操作符)

  1. 算數運算子(加、減、乘、除、商、餘、自加、自減)

    print(20 + 2);  // 22   加
    print(20 - 2);  // 18   減
    print(20 * 2);  // 40   乘
    print(20 / 2);  // 10   除
    print(40 ~/ 3); // 13   商
    print(40 % 3);  // 1    餘
    
    // i++
    int i = 3;
    var a = i++; // 賦值後i才自加,故a=3
    print('a=$a,i=$i'); // a=3,i=4
    
    // ++i
    int i = 3;
    var a = ++i; // 執行賦值前i已經自加,故a=4
    print('a=$a,i=$i'); // a=4,i=4
    
    // i--
    int i = 3;
    var a = i--; // 執行賦值後i才自減,故a=3
    print('a=$a,i=$i'); // a=3,i=2
    
    --i
    int i = 3;
    var a = --i; // 執行賦值前i已經自減,故a=2
    print('a=$a,i=$i'); // a=2,i=2
    複製程式碼
  2. 關係運算子(大於、小於、等於、不等於、大於等於、小於等於)

    print(10 > 20);     // false    大於
    print(10 < 20);     // true     小於
    print(10 == 20);    // false    等於
    print(10 != 20);    // true     不等
    print(10 >= 3);     // true  大於等於
    print(10 <= 3);     // false 小於等於
    複製程式碼
  3. 位運算子(位與、位或、位非、異或、左移、右移)

    // 位與:& 兩個都是1為1 
    // 位或:| 只要有1就是1
    // 位非:~ 全取反
    // 異或:^ 位都不一樣為1
    // 左移:<< 整體左移,不足補0             
    // 右移:>> 整體右移
    複製程式碼
  4. 邏輯運算子(邏輯與、邏輯或、邏輯非)

    bool isGreen = true;
    bool isBlack = false;
    print("${isGreen && isBlack}"); // false 邏輯與
    print("${isGreen || isBlack}"); // true  邏輯或
    print("${!isBlack}");           // true  邏輯非
    複製程式碼
  5. 賦值運算子

    =
    ??      // AA ?? "99" 表示如果 AA 為空,返回99
    ??=     // AA ??= "99"如果 AA 為空,給 AA 設定成 99
    +=
    -=
    *=
    /=
    ~/=
    %=
    <<=
    =>>
    &=
    |=
    ^=
    複製程式碼
  6. 條件表示式

    expr1 ? expr2 : expr3 // 三目運算子 如果 if(expr1) expr2 else expr3
    expr1 ?? expr2 // expr1 ? expr1 : expr2
    複製程式碼
  7. 型別測試操作符

    as : 型別轉換
    is : 當物件是相應型別時返回 true
    is! : 當物件不是相應型別時返回 true

JIT 和 AOT

  • JIT(Just In Time):即時編譯,在程式執行中將熱點程式碼編譯成機器碼,以提升開發效率。JIT可以充分利用解釋型語言的優點,動態執行原始碼,而不用考慮平臺差異性,JIT模式需要配合DartVM使用。
  • AOT(Ahead Of Time):執行前編譯,在程式執行之前,已經編譯成對應平臺的機器碼,不需要在執行中解釋編譯就可以直接執行,AOT需要使用runtime來執行。
  • 四種編譯模式
  1. Script:最常見的JIT模式,可以直接在虛擬機器中執行Dart原始碼,像解釋型語言一樣使用。通過 Dart xxx.dart直接執行,適合寫一些臨時指令碼。
  2. Kernel Snapshots:也是JIT模式,又稱為Script Snapshots,和Script不同的是,這種模式執行的是Kernel AST的二進位制資料,這裡不包含解析後的類和函式以及編譯後的程式碼,所以不能在不同平臺之間移植。 Dart Kernel是Dart程式中一種中間語言,可通過 dart --snapshot-kind=kernel --snapshot=xxx.snapshot xxx.dart 生成
  3. JIT Application Snapshots:也是JIT模式,執行的是解析過的類和函式以及編譯後的程式碼,所以執行更快,但只能針對32位或64位架構執行,可通過 dart --snapshot-kind=app-jit --snapshot=xxx.snapshot xxx.dart 生成
  4. AOT Application Snapshots:AOT模式,原始碼被提前編譯成特定平臺的二進位制檔案。要用AOT模式,需要dart2aot命令,如dart2aot xxx.dart xxx.dart.aot然後用 dartaotruntime命令執行

斷言 assert

  • assert(條件) 如果條件不滿足,會中斷程式的執行,否則繼續執行

參考文章

上一頁 Flutter1 環境搭建
下一頁 Flutter3 基本型別

相關文章