初識Flutter(基礎入門)

Content:


Flutter框架概況

發展概述

Flutter是Google開發的一套全新的跨平臺、開源UI框架,可以快速在iOS和Android上構建高質量的原生用戶界面。 Flutter可以與現有的代碼一起工作。在全世界,Flutter正在被越來越多的開發者和組織使用,并且Flutter是完全免費、開源的。它也是構建未來的Google Fuchsia應用的主要方式及其默認開發套件。

Flutter組件采用現代響應式框架構建,這是從React中獲得的靈感,中心思想是用組件(widget)構建你的UI。組件描述了在給定其當前配置和狀態時他們顯示的樣子。當組件狀態改變,組件會重構它的描述(description),Flutter會對比之前的描述,以確定底層渲染樹從當前狀態轉換到下一個狀態所需要的最小更改。

發展歷史

自從2017年5月發布第一個版本以來,目前Flutter已經發布了近60個版本,并且在2018年5月發布了第一個“Ready for Production Apps”的Beta 3版本,6月20日發布了第一個“Release Preview”版本。

  • Flutter的第一個版本被稱為“Sky”,運行在Android操作系統是。它是在2015年Dart開發者峰會 [3] 上亮相的,其目的是能夠以每秒120幀的速度持續渲染。
  • Beta1版本于2018年2月27日在2018 世界移動大會公布。
  • Beta2版本2018年3月6日發布。

框架特性

  • Fast development(快速開發)
  • Expressive and Flexible UI(富有表現力和靈活的UI)
  • Native Performance(原生性能)
  • Modern, reactive framework(現代的,響應式框架)
  • Access native features and SDKs(訪問本地功能和SDK)
  • Unified app development(統一標準的應用開發體驗)

Fast development(快速開發)

Flutter的熱重載可幫助您快速地進行測試、構建UI、添加功能并更快地修復錯誤。在iOS和Android模擬器或真機上可以在亞秒內重載,并且不會丟失狀態。

hot-reload.gif

xpressive and Flexible UI(富有表現力和靈活的UI)

使用Flutter內置美麗的Material Design和Cupertino(iOS風格)widget、豐富的motion API、平滑而自然的滑動效果和平臺感知,為您的用戶帶來全新體驗。

screenshot-1.png
screenshot-2.png

Modern, reactive framework(現代的,響應式框架)

使用Flutter的現代、響應式框架,和一系列基礎widget,輕松構建您的用戶界面。使用功能強大且靈活的API(針對2D、動畫、手勢、效果等)解決艱難的UI挑戰。

class CounterState extends State<Counter> {
  int counter = 0;

  void increment() {
    // 告訴Flutter state已經改變, Flutter會調用build(),更新顯示
    setState(() {
      counter++;
    });
  }

  Widget build(BuildContext context) {
    // 當 setState 被調用時,這個方法都會重新執行.
    // Flutter 對此方法做了優化,使重新執行變的很快
    // 所以你可以重新構建任何需要更新的東西,而無需分別去修改各個widget
    return new Row(
      children: <Widget>[
        new RaisedButton(
          onPressed: increment,
          child: new Text('Increment'),
        ),
        new Text('Count: $counter'),
      ],
    );
  }
}

Access native features and SDKs(訪問本地功能和SDK

通過平臺相關的API、第三方SDK和原生代碼讓您的應用變得強大易用。 Flutter允許您復用現有的Java、Swift或ObjC代碼,訪問iOS和Android上的原生系統功能和系統SDK。

Future<Null> getBatteryLevel() async {
  var batteryLevel = 'unknown';
  try {
    int result = await methodChannel.invokeMethod('getBatteryLevel');
    batteryLevel = 'Battery level: $result%';
  } on PlatformException {
    batteryLevel = 'Failed to get battery level.';
  }
  setState(() {
    _batteryLevel = batteryLevel;
  });
}

Unified app development(統一標準的應用開發體驗)

Flutter擁有豐富的工具和庫,可以幫助您輕松地同時在iOS和Android系統中實現您的想法和創意。 如果您沒有任何移動端開發體驗,Flutter是一種輕松快捷的方式來構建漂亮的移動應用程序。 如果您是一位經驗豐富的iOS或Android開發人員,則可以使用Flutter作為視圖(View)層, 并可以使用已經用Java / ObjC / Swift完成的部分(Flutter支持混合開發)。

  1. 構建
    漂亮的用戶界面
    • 豐富的2D GPU加速API
    • 響應式框架
    • 動畫/運動API
    • Material組件和Cupertino widgets
    流暢的編碼體驗
    -亞秒級,有狀態的熱重載
    • IntelliJ: 代碼重構、補全等
    • Dart語言和核心庫
    • 包管理器
    全功能的應用程序
    • 與移動操作系統API和SDK交互
    • Maven/Java
    • Cocoapods/ObjC/Swift
  2. 優化
    測試
    • 單元測試
    • 集成測試
    • 設備上測試
    調試
    • IDE 調試器
    • 基于Web的調試器
    • async/await aware
    • Expression evaluator
    性能分析
    • 時間線(Timeline)
    • CPU和內存
    • 應用內性能圖標
  3. 部署
    編譯
    • Native ARM 代碼
    • Dead code elimination
    發布
    • App Store
    • Play Store

了解詳細的Flutter技術總覽:

框架結構

Flutter的主要結構包括:

  • Flutter engine
  • Foundation library
  • Design-specific widgets

快速入門

安裝Flutter在Mac OS上

使用鏡像

由于在國內訪問Flutter有時可能會受到限制,Flutter官方為中國開發者搭建了臨時鏡像,大家可以將如下環境變量加入到用戶環境變量中:
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

獲取Flutter SDK

  1. 去flutter官網下載其最新可用的安裝包,下載地址:Flutter SDK。當然在國內,大家懂得,如果想要正常獲取到安裝包列表或者下載安裝包,可能需要VPN的幫助,也可以去Flutter github項目去下載最新的安裝包,下載地址為:Flutter Github
  2. 下載好壓縮包后解壓到你想安裝到的目錄下(切記是你想安裝到的目錄下,如果你要直接安裝到desktop,那當然也ok),如:
EchoZuo-work-MBP:/ EchoZuo$ cd users/echozuo/
EchoZuo-work-MBP:echozuo EchoZuo$  unzip ~/Downloads/flutter_macos_v0.5.1-beta.zip
  1. 添加flutter相關工具到path中,如:
export PATH=`pwd`/flutter/bin:$PATH

此代碼只能暫時針對當前命令行窗口設置PATH環境變量,要想永久將Flutter添加到PATH中請參考下面 更新環境變量 部分。

運行 flutter doctor
運行以下命令來檢查是否還需要安裝其他依賴項或者是否有安裝錯誤產生:
flutter doctor
該命令檢查您的環境并在終端窗口中顯示報告。Dart SDK已經在捆綁在Flutter里了,沒有必要單獨安裝Dart。 仔細檢查命令行輸出以獲取可能需要安裝的其他軟件或進一步需要執行的任務(以粗體以及錯誤符號x展示)
如:
[-] Android toolchain - develop for Android devices
    ? Android SDK at /Users/obiwan/Library/Android/sdk
    ? Android SDK is missing command line tools; download from https://goo.gl/XxQghQ
    ? Try re-installing or updating your Android SDK,
      visit https://flutter.io/setup/#android-setup for detailed instructions.
一般的錯誤會是xcode或Android Studio版本太低、或者沒有ANDROID_HOME環境變量等,請按照提示解決。Mac OS 的環境變量配置,可以對比修正下:
  export PATH=/Users/用戶名/Documents/flutter/flutter/bin:$PATH
  export ANDROID_HOME="/Users/用戶名/Documents/android_sdk" //android sdk目錄,替換為你自己的即可
  export PATH=${PATH}:${ANDROID_HOME}/tools
  export PATH=${PATH}:${ANDROID_HOME}/platform-tools
  export PUB_HOSTED_URL=https://pub.flutter-io.cn
  export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn

切記設置好對應SDK的環境變量,否則無法安裝flutter成功。

第一次運行一個flutter命令(如flutter doctor)時,它會下載它自己的依賴項并自行編譯。以后再運行就會快得多。
以下各部分介紹如何執行這些任務并完成設置過程。你會看到在flutter doctor輸出中, 如果你選擇使用IDE,我們提供了,IntelliJ IDEA,Android Studio和VS Code的插件。
一旦你安裝了任何缺失的依賴,再次運行flutter doctor命令來驗證你是否已經正確地設置了。

該flutter工具使用Google Analytics匿名報告功能使用情況統計信息和基本崩潰報告。 這些數據用于幫助改進Flutter工具。Analytics不是一運行或在運行涉及flutter config的任何命令時就發送, 因此您可以在發送任何數據之前退出分析。要禁用報告,請執行flutter config --no-analytics并顯示當前設置,然后執行flutter config。

編譯器設置

使用 flutter 命令行工具,您可以使用任何編輯器來開發Flutter應用程序。輸入flutter help在提示符下查看可用的工具。建議使用的插件來獲得豐富的IDE體驗,支持編輯,運行和調試Flutter應用程序。個人比較喜歡微軟的VS Code編譯器,界面也比較新穎美觀,相對于Android Studio,在Max OS上VS Code啟動更快速也不卡頓。

Visual Studio Code (VS Code) 安裝和相關配置

VS Code: 輕量級編輯器,支持Flutter運行和調試.
安裝 VS Code
  • VS Code, 安裝1.20.1或更高版本.
安裝Flutter插件
  1. 啟動 VS Code
  2. 調用 View>Command Palette…
  3. 輸入 ‘install’, 然后選擇 Extensions: Install Extension action
  4. 在搜索框輸入 flutter , 在搜索結果列表中選擇 ‘Flutter’, 然后點擊 Install
  5. 選擇 ‘OK’ 重新啟動 VS Code

VS Code很多的相關設置都是聽過插件或者命令行去處理,如果不習慣的話可以使用Android Studio或者IntelliJ。Android Studio的配置請參考配置編輯器

通過Flutter Doctor驗證您的設置

  1. 調用 View>Command Palette…
  2. 輸入 ‘doctor’, 然后選擇 ‘Flutter: Run Flutter Doctor’ action
  3. 查看“OUTPUT”窗口中的輸出是否有問題。(這里請仔細查看控制臺輸出,如果沒有看到控制臺,可以通過快捷鍵shift+command+U調出控制臺)

開發平臺設置

macOS支持為iOS和Android開發Flutter應用程序。現在完成兩個平臺設置步驟中的至少一個,以便能夠構建并運行您的第一個Flutter應用程序

iOS 設置(如果你是一個iOS開發工作者,下述iOS的相關設置可以粗略帶過)

安裝Xcode
要為iOS開發Flutter應用程序,您需要Xcode 7.2或更高版本:
  1. 安裝Xcode 7.2或更新版本
  2. 配置Xcode命令行工具以使用新安裝的Xcode版本 sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer 對于大多數情況,當您想要使用最新版本的Xcode時,這是正確的路徑。如果您需要使用不同的版本,請指定相應路徑。
  3. 確保Xcode許可協議是通過打開一次Xcode或通過命令sudo xcodebuild -license同意過了.
使用Xcode,您可以在iOS設備或模擬器上運行Flutter應用程序
設置iOS模擬器
要準備在iOS模擬器上運行并測試您的Flutter應用,請按以下步驟操作:
  1. 在Mac上,通過Spotlight或使用以下命令找到模擬器:
open -a Simulator
  1. 通過檢查模擬器 硬件>設備 菜單中的設置,確保您的模擬器正在使用64位設備(iPhone 5s或更高版本).
  2. 根據您的開發機器的屏幕大小,模擬的高清屏iOS設備可能會使您的屏幕溢出。在模擬器的 Window> Scale 菜單下設置設備比例
  3. 運行 flutter run啟動您的應用.
安裝到iOS設備
要將您的Flutter應用安裝到iOS真機設備,您需要一些額外的工具和一個Apple帳戶,您還需要在Xcode中進行設置。
  1. 安裝 homebrew (如果已經安裝了brew,跳過此步驟).
  2. 打開終端并運行這些命令來安裝用于將Flutter應用安裝到iOS設備的工具
brew update
brew install --HEAD libimobiledevice
brew install ideviceinstaller ios-deploy cocoapods
pod setup
如果這些命令中的任何一個失敗并出現錯誤,請運行brew doctor并按照說明解決問題.

Android設置

安裝Android Studio
要為Android開發Flutter應用,您可以使用Mac,Windows或Linux(64位)機器.
Flutter需要安裝和配置Android Studio:
  1. 下載并安裝 Android Studio.
  2. 啟動Android Studio,然后執行“Android Studio安裝向導”。這將安裝最新的Android SDK,Android SDK平臺工具和Android SDK構建工具,這是Flutter為Android開發時所必需的
設置您的Android設備
要準備在Android設備上運行并測試您的Flutter應用,您需要安裝Android 4.1(API level 16)或更高版本的Android設備.
  1. 在您的設備上啟用 開發人員選項 和 USB調試 。詳細說明可在Android文檔中找到。
  2. 使用USB將手機插入電腦。如果您的設備出現提示,請授權您的計算機訪問您的設備。
  3. 在終端中,運行 flutter devices 命令以驗證Flutter識別您連接的Android設備。
  4. 運行啟動您的應用程序 flutter run。
默認情況下,Flutter使用的Android SDK版本是基于你的 adb 工具版本。 如果您想讓Flutter使用不同版本的Android SDK,則必須將該 ANDROID_HOME 環境變量設置為SDK安裝目錄。
設置安卓模擬器
要準備在Android模擬器上運行并測試您的Flutter應用,請按照以下步驟操作:
  1. 在您的機器上啟用 VM acceleration .
  2. 啟動 Android Studio>Tools>Android>AVD Manager 并選擇 Create Virtual Device.
  3. 選擇一個設備并選擇 Next。
  4. 為要模擬的Android版本選擇一個或多個系統映像,然后選擇 Next. 建議使用 x86 或 x86_64 image .
  5. 在 Emulated Performance下, 選擇 Hardware - GLES 2.0 以啟用 硬件加速.
  6. 驗證AVD配置是否正確,然后選擇 Finish。
  7. 在 Android Virtual Device Manager中, 點擊工具欄的 Run。模擬器啟動并顯示所選操作系統版本或設備的啟動畫面.
  8. 運行 flutter run 啟動您的設備. 連接的設備名是 Android SDK built for <platform>,其中 platform 是芯片系列, 如 x86.

初步體驗

先體驗一下Flutter App(使用VS Code)

創建新的應用

  1. 啟動VS Code
  2. 調用 View>Command Palette…(默認快捷鍵為shift+cmd+P),如果你的VS Code為中文版本,則為試圖>命令面板
  3. 輸入 ‘flutter’, 然后選擇 ‘Flutter: New Project’ action
  4. 輸入 Project 名稱, 然后按回車鍵
  5. 指定放置項目的位置,然后按藍色的確定按鈕
  6. 等待項目創建繼續,并顯示main.dart文件
上述命令創建一個Flutter項目,項目名為myfirstflutterappnew(自己建立的項目名稱),其中包含一個使用Material 組件的簡單的演示應用程序。
在項目目錄中,您的應用程序的代碼位于 lib/main.dart.
順便看一下建立完之后的項目文件結構:
項目1.png

如果沒有問題,現在可以開始運行應用程序

  1. 確保在VS Code的右下角選擇了目標設備
  2. 按 F5 鍵或調用Debug>Start Debugging
  3. 等待應用程序啟動
  4. 如果一切正常,在應用程序建成功后,您應該在您的設備或模擬器上看到應用程序:


    Simulator Screen Shot - iPhone XS Max - 2018-09-26 at 14.54.11.png

體驗熱重載

Flutter 可以通過 熱重載(hot reload) 實現快速的開發周期,熱重載就是無需重啟應用程序就能實時加載修改后的代碼,并且不會丟失狀態(譯者語:如果是一個web開發者,那么可以認為這和webpack的熱重載是一樣的)。簡單的對代碼進行更改,然后告訴IDE或命令行工具你需要重新加載(點擊reload按鈕),你就會在你的設備或模擬器上看到更改。
  1. 用你喜歡的編輯器打開文件lib/main.dart
  2. 隨意更改代碼中的字符串,例如將'Flutter Demo Home Page'更改為'神奇的Flutter'
  3. 不要按“停止”按鈕; 讓您的應用繼續運行.
  4. 要查看您的更改,請調用 Save (cmd-s / ctrl-s), 或者點擊 熱重載按鈕 (綠色圓形箭頭按鈕).
你會立即在運行的應用程序中看到更新的字符串

編寫第一個Flutter App

我們將制作一個無限滾動的list,這個 GIF 圖展示了最終實現的效果:
  • Flutter 可以在 Android 和 iOS 系統里自動適應不同的 UI 體系
  • Flutter 工程/項目的基本結構
  • 查找和使用 packages 來擴展功能
  • 使用熱重載加快開發周期
  • 如何實現有狀態的 widget
  • 如何創建一個無限的、延遲加載的列表


    e3624172607d5551.png

1.配置Flutter開發環境,如果沒有配置,請翻到“快速入門”模塊對照進行配置

2.創建初始化工程

  • 創建一個簡單的、基于模板的 Flutter 工程,按照這個指南中所描述的步驟,然后將項目命名為 startup_namer(而不是 myapp)

在這個示例中,你將主要編輯 Dart 代碼所在的 lib/main.dart 文件中

  • lib/main.dart
刪除 lib/main.dart 中的所有代碼,然后替換為下面的代碼,它將在屏幕的中心顯示"Hello World"
import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: const Text('Welcome to Flutter'),
        ),
        body: const Center(
          child: const Text('Hello World'),
        ),
      ),
    );
  }
}
222.png
  • 觀察和分析
    • 本示例創建了一個具有 Material Design 風格的應用,Material 是一種移動端和網頁端通用的視覺設計語言,Flutter 提供了豐富的 Material 風格的 widgets。
    • 主函數(main)使用了 (=>) 符號,這是 Dart 中單行函數或方法的簡寫。
    • 該應用程序繼承了 StatelessWidget,這將會使應用本身也成為一個 widget。在 Flutter 中,大多數東西都是 widget,包括對齊 (alignment)、填充 (padding) 和布局 (layout)。
    • Scaffold 是 Material library 中提供的一個 widget,它提供了默認的導航欄、標題和包含主屏幕 widget 樹的 body 屬性。widget 樹可以很復雜。
    • 一個 widget 的主要工作是提供一個 build() 方法來描述如何根據其他較低級別的 widgets 來顯示自己。
    • 本示例中的 body 的 widget 樹中包含了一個 Center widget,Center widget 又包含一個 Text 子 widget,Center widget 可以將其子 widget 樹對其到屏幕中心。

3.使用package

在這一步中,你將開始使用一個名為english_words 的開源軟件包,其中包含數千個最常用的英文單詞以及一些實用功能。
你可以 在 pub.dartlang.org 上找到 english_words 軟件包以及其他許多開源軟件包。
  • pubspec 文件管理 Flutter 應用程序的 assets(資源,如圖片、package等)。 在pubspec.yaml 中,將 english_words(3.1.0或更高版本)添加到依賴項列表,如下面高亮顯示的行:
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^0.1.0
  english_words: ^3.1.0   # 新增了這一行
  • 在Android Studio 的編輯器視圖中查看 pubspec 時,單擊右上角的 Packages get,這會將依賴包安裝到您的項目。您可以在控制臺中看到以下內容:
flutter packages get
Running "flutter packages get" in startup_namer...
Process finished with exit code 0
  • 在 lib/main.dart 中引入,如下所示:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';  // 新增了這一行
在您輸入時,Android Studio會為您提供有關庫導入的建議。然后它將呈現灰色的導入字符串,讓您知道導入的庫截至目前尚未被使用。
接下來,我們使用 English words 包生成文本來替換字符串"Hello World":
  • 我們需要進行如下更改:
import 'package:flutter/material.dart';
import 'package:english_words/english_words.dart';

void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final wordPair = new WordPair.random(); // 新增了這一行
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(    // 這里把之前的 "const" 換成了 "new".
          //child: const Text('Hello World'),   // 我們不用這樣的方式生成文字了
          child: new Text(wordPair.asPascalCase),  // 這是新的文字生成方式
        ),
      ),
    );
  }
}
如果你沒有把 Center 前面的修飾詞從 const 改成 new 的話,系統就會報錯,因為這個時候它的子對象已經不是常量,那就不能再用 const 了,所以這里 Center 和 Text 都需要使用 new 創建新的實例。
  • 如果應用程序正在運行,請使用熱重載按鈕更新正在運行的應用程序。每次單擊熱重載或保存項目時,都會在正在運行的應用程序中隨機選擇不同的單詞對。 這是因為單詞對是在 build 方法內部生成的。每次 MaterialApp 需要渲染時或者在 Flutter Inspector 中切換平臺時 build 都會運行.
1111.png

4.添加一個 Stateful widget

Stateless widgets 是不可變的,這意味著它們的屬性不能改變——所有的值都是 final。
Stateful widgets 持有的狀態可能在 widget 生命周期中發生變化,實現一個 stateful widget 至少需要兩個類:1)一個 StatefulWidget 類;2)一個 State 類,StatefulWidget 類本身是不變的,但是 State 類在 widget 生命周期中始終存在。
在這一步,你將添加一個 stateful widget(有狀態的控件)—— RandomWords,它會創建自己的狀態類 —— RandomWordsState,然后你需要將 RandomWords 內嵌到已有的無狀態的 MyApp widget。
  • 創建一個最簡的 state 類,這個類可以在任意地方創建而不一定非要在 MyApp 里,我們的示例代碼是放在 MyApp 類的最下面了:
class RandomWordsState extends State<RandomWords> {
  // TODO Add build method
}
注意一下 State<RandomWords> 的聲明。這表明我們在使用專門用于 RandomWords 的 State 泛型類。應用的大部分邏輯和狀態都在這里 —— 它會維護 RandomWords 控件的狀態。這個類會保存代碼生成的單詞對,這個單詞對列表會隨著用戶滑動而無限增長,另外還會保存用戶喜愛的單詞對(第二部分),也即當用戶點擊愛心圖標的時候會從喜愛的列表中添加或者移除當前單詞對。
RandomWordsState 繼承自 RandomWords,我們接下來會創建這個類。
  • 添加有狀態的 RandomWords widget 到 main.dart,RandomWords widget 除了創建 State 類之外幾乎沒有其他任何東西:
class RandomWords extends StatefulWidget {
  @override
  RandomWordsState createState() => new RandomWordsState();
}
在添加狀態類后,IDE 會提示該類缺少 build 方法。接下來,您將添加一個基本的 build 方法,該方法通過將生成單詞對的代碼從 MyApp 移動到 RandomWordsState 來生成單詞對。
  • build 方法添加到 RandomWordState 中,如下所示:
class RandomWordsState extends State<RandomWords> {
  @override                                  // 新增代碼片段 - 開始 ... 
  Widget build(BuildContext context) {
    final WordPair wordPair = new WordPair.random();
    return new Text(wordPair.asPascalCase);
  }                                          // ... 新增的代碼片段 - 結束
}
  • 如下所示,刪除 MyApp 里生成文字的代碼:
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    final WordPair wordPair = new WordPair.random();  // 刪掉本行
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('Welcome to Flutter'),
        ),
        body: new Center(
          //child: new Text(wordPair.asPascalCase), // 修改本行內容 
          child: new RandomWords(),                 // 修改成本行代碼
        ),
      ),
    );
  }
}
  • 熱重載(Hot reload)當前的工程,應用應該像之前一樣運行,每次熱重載或保存應用程序時都會顯示一個單詞對。

5.創建一個無限滾動的 ListView

在這一步中,您將擴展(繼承)RandomWordsState 類,以生成并顯示單詞對列表。 當用戶滾動時,ListView 中顯示的列表將無限增長。 ListView 的 builder 工廠構造函數允許您按需建立一個懶加載的列表視圖。
  • 向 RandomWordsState 類中添加一個 _suggestions 列表以保存建議的單詞對,同時,添加一個 biggerFont 變量來增大字體大小 Also, add a _biggerFont variable for making the font size larger.

提示:在 Dart 語言中使用下劃線前綴標識符,會強制其變成私有。

class RandomWordsState extends State<RandomWords> {
  // 添加如下兩行
  final List<WordPair> _suggestions = <WordPair>[];
  final TextStyle _biggerFont = const TextStyle(fontSize: 18.0); 
  ...
}
接下來,我們將向 RandomWordsState 類添加一個 _buildSuggestions()) 函數,此方法構建顯示建議單詞對的 ListView。
ListView 類提供了一個 builder 屬性,itemBuilder 值是一個匿名回調函數, 接受兩個參數- BuildContext 和行迭代器 i。迭代器從 0 開始, 每調用一次該函數,i 就會自增 1,對于每個建議的單詞對都會執行一次。該模型允許建議的單詞對列表在用戶滾動時無限增長。
  • RandomWordsState 類添加 _buildSuggestions() 函數,內容如下:
Widget _buildSuggestions() {
    return new ListView.builder(
      padding: const EdgeInsets.all(16.0),

      // 對于每個建議的單詞對都會調用一次 itemBuilder,
      // 然后將單詞對添加到 ListTile 行中
      // 在偶數行,該函數會為單詞對添加一個 ListTile row.
      // 在奇數行,該行書湖添加一個分割線 widget,來分隔相鄰的詞對。
      // 注意,在小屏幕上,分割線看起來可能比較吃力。

      itemBuilder: (BuildContext _context, int i) {
        // 在每一列之前,添加一個1像素高的分隔線widget
        if (i.isOdd) {
          return new Divider();
        }

        // 語法 "i ~/ 2" 表示i除以2,但返回值是整形(向下取整)
        // 比如 i 為:1, 2, 3, 4, 5 時,結果為 0, 1, 1, 2, 2,
        // 這可以計算出 ListView 中減去分隔線后的實際單詞對數量
        final int index = i ~/ 2;
        // 如果是建議列表中最后一個單詞對
        if (index >= _suggestions.length) {
        // ...接著再生成10個單詞對,然后添加到建議列表
          _suggestions.addAll(generateWordPairs().take(10));
        }
        return _buildRow(_suggestions[index]);
      }
    );
  }
對于每一個單詞對,_buildSuggestions 函數都會調用一次 _buildRow。 這個函數在 ListTile 中顯示每個新詞對,這使您在下一步中可以生成更漂亮的顯示行,詳見本 codelab 的第二部分。
  • RandomWordsState 中添加 _buildRow 函數 :
  Widget _buildRow(WordPair pair) {
    return new ListTile(
      title: new Text(
        pair.asPascalCase,
        style: _biggerFont,
      ),
    );
  }
  • 更新 RandomWordsState 的 build 方法以使用 _buildSuggestions(),而不是直接調用單詞生成庫,代碼更改后如下:(使用 Scaffold 類實現基礎的 Material Design 布局)
  @override
  Widget build(BuildContext context) {
    //final wordPair = new WordPair.random(); // 刪掉 ... 
    //return new Text(wordPair.asPascalCase); // ... 這兩行

    return new Scaffold (                   // 代碼從這里... 
      appBar: new AppBar(
        title: new Text('Startup Name Generator'),
      ),
      body: _buildSuggestions(),
    );                                      // ... 添加到這里
  }
  • 更新 MyApp 的 build 方法, changing the title, and changing the home to be a RandomWords widget.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Startup Name Generator',
      home: new RandomWords(),
    );
  }
  • 重新啟動你的項目工程應用,你應該看到一個單詞對列表。盡可能地向下滾動,你將繼續看到新的單詞對。
d71590c8c3c2e6f8.png

至此,我們的第一個無限滾得的Flutter頁面開發完成。后續會再進行拓展更多的功能。

更多細節

為什么要使用Flutter?

Flutter則開辟了一種全新的思路,從頭到尾重寫一套跨平臺的UI框架,包括UI控件、渲染邏輯甚至開發語言。渲染引擎依靠跨平臺的Skia圖形庫來實現,依賴系統的只有圖形繪制相關的接口,可以在最大程度上保證不同平臺、不同設備的體驗一致性,邏輯處理使用支持AOT的Dart語言,執行效率也比JavaScript高得多。
Flutter同時支持Windows、Linux和macOS操作系統作為開發環境,并且在Android Studio和VS Code兩個IDE上都提供了全功能的支持。Flutter所使用的Dart語言同時支持AOT和JIT運行方式,JIT模式下還有一個備受歡迎的開發利器“熱刷新”(Hot Reload),即在Android Studio中編輯Dart代碼后,只需要點擊保存或者“Hot Reload”按鈕,就可以立即更新到正在運行的設備上,不需要重新編譯App,甚至不需要重啟App,立即就可以看到更新后的樣式。
在Flutter中,所有功能都可以通過組合多個Widget來實現,包括對齊方式、按行排列、按列排列、網格排列甚至事件處理等等。Flutter控件主要分為兩大類,StatelessWidget和StatefulWidget,StatelessWidget用來展示靜態的文本或者圖片,如果控件需要根據外部數據或者用戶操作來改變的話,就需要使用StatefulWidget。State的概念也是來源于Facebook的流行Web框架React ,React風格的框架中使用控件樹和各自的狀態來構建界面,當某個控件的狀態發生變化時由框架負責對比前后狀態差異并且采取最小代價來更新渲染結果。

Flutter是一款移動應用程序SDK,一份代碼可以同時生成iOS和Android兩個高性能、高保真的應用程序。Flutter目標是使開發人員能夠交付在不同平臺上都感覺自然流暢的高性能應用程序。我們兼容滾動行為、排版、圖標等方面的差異。

QQ20180925-194235@2x.png

這是一個來自Gallery的演示應用程序, 您可以在安裝Flutter并設置好環境后運行Flutter示例應用程序。“Shrine”示例擁有高質量的滾動圖片、互動卡片、按鈕、下拉列表和購物車頁面。 要查看這個和更多示例的代碼,請訪問我們的GitHub

無需移動開發經驗即可開始使用。應用程序是用Dart語言編寫的,如果您使用過Java或JavaScript之類的語言,則該應用程序看起來很熟悉。 使用面向對象語言的經驗絕對有幫助,但一些Flutter應用程序甚至是沒有編程經驗的人寫的!

Flutter的優勢

  • 提高開發效率
    • 同一份代碼開發iOS和Android
    • 用更少的代碼做更多的事情
    • 輕松迭代
      • 在應用程序運行時更改代碼并重新加載(通過熱重載)(熱重載特別方便快速運行看到效果,個人很喜歡)
      • 修復崩潰并繼續從應用程序停止的地方進行調試
  • 創建美觀,高度定制的用戶體驗
    • 受益于使用Flutter框架提供的豐富的Material Design和Cupertino(iOS風格)的widget
    • 實現定制、美觀、品牌驅動的設計,而不受原生控件的限制

核心原則

Flutter包括一個現代的響應式框架、一個2D渲染引擎、現成的widget和開發工具。這些組件可以幫助您快速地設計、構建、測試和調試應用程序。

一切皆為widget

Widget是Flutter應用程序用戶界面的基本構建塊。每個Widget都是用戶界面一部分的不可變聲明。 與其他將視圖、控制器、布局和其他屬性分離的框架不同,Flutter具有一致的統一對象模型:widget。
Widget可以被定義為:
  • 一個結構元素(如按鈕或菜單)
  • 一個文本樣式元素(如字體或顏色方案)
  • 布局的一個方面(如填充)
  • 等等…

其他

文章說明

  • 本文僅供用于學習參考,請勿用于商業用途。如需轉載,請標明出處,謝謝合作。
  • 本文系參考網絡公開Flutter學習資料以及個人學習體會總結所得,部分內容為網絡公開學習資料,如有侵權請聯系作者刪除。

參考文章

作者資料

就職于甜橙金融(翼支付)信息技術部,負責翼支付iOS客戶端開發。喜歡研究新的技術,喜歡Apple、喜歡數碼。大家可以一起探討一起學習。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,661評論 25 708
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,788評論 2 59
  • 谷歌的 Flutter 為開發人員提供了一種構建 Android 和 iOS 原生用戶界面的方法,為開發人員減少了...
    高級java架構師閱讀 9,192評論 1 40
  • 今天我和媽媽一起去小區門口的照相館去照相,照完相出來,無意中發現了一家牛肉面館,外面門小小的,窗戶大大的,周圍綠樹...
    唐啟云閱讀 141評論 0 0
  • 親愛的小伙伴 我們是否有心靈感應呢? 一個平常不能再平常的午后,如往常一樣百無聊賴的翻閱著微信公眾號,然后...
    懶靜閱讀 497評論 5 9