給 iOS ⼯工程師的
Flutter 開發
zonble

zonble@gmail.com
Flutter
• https://flutter.io

• ⼀一個寄宿在⽬目前 iOS、Android 平台上的新平台

• 是設計給 Google 未來來作業系統 Fuchsia 的應⽤用程式開發層

• Dart VM + Skia Render 引擎

• 在 iOS/Android App 中包入 Flutter Framework 後,執⾏行行 Dart
code,同⼀一個 App 在不同平台可以 render 出相同的效果

• 可以與 ObjC/Swift/Java/Kotlin 橋接

• 重新發明 Flash?
⽤用 Flutter 可能有什什麼好處?
• 以⽬目前的執⾏行行效能與完成度來來看,似乎不能不管

• 如果同時需要開發 iOS/Android,可以⼤大量量共⽤用程式碼

• iOS/Android 上可以 Render 出⼀一樣的畫⾯面,設計師可以只
需要做⼀一套設計

• 現在就先投資未來來的 Google 作業系統,以及 Flutter 還可
能移植到 Windows/Mac/瀏覽器執⾏行行的可能
⽤用 Flutter 會犧牲什什麼
• 還不⽀支援⼀一些 iPhone 的特殊功能,如 3D Touch

• 不過你的 App 本來來也就沒在⽀支援 3D Touch

• 犧牲跟 macOS/tvOS/watchOS 共⽤用程式碼的機會

• 不過你本來來也沒在⽀支援

• 好的 Dart 語⾔言的⼯工程師不好找

• 不過反正你本來來也找不到好的 ObjC/Swift/Java/Kotlin ⼯工
程師
⽤用 Flutter 會犧牲什什麼
• 在 iOS 上由於⽤用的不是 UIKit 元件,看起來來會比較像
Google Photo 的感覺,⽽而不像「很 Apple」的 App

• 無法使⽤用 XCTest 測試

• 上線後,從 iOS 的 crash log 中看不出 Dart 程式的問題

• 專案會與 Firebase 變得更更緊密,因為現在供 Flutter 使⽤用的
BaaS、Analytics…都只有 Firebase 這個選擇
使⽤用 Flutter 的挑戰
• Flutter 無法使⽤用⼀一些平台專屬功能,⽽而可能需要寫與該平
台橋接的程式,所以現階段還是得懂⼀一定的 iOS/Android
開發

• 哪些部分⽤用 Flutter 寫,哪些寫在 iOS/Android 橋接端,非
常挑戰 App 架構的能⼒力力
安裝
• 先裝好 Xcode 以及 Android Studio

• 去 https://flutter.io/setup-macos/ 下載 zip 檔解壓

• 執⾏行行 flutter doctor 看看少了了什什麼

• ⽤用 homebrew 裝 ideviceinstaller 以及 ios-deploy

• IDE 可⽤用 Android Studio 或 VSCode
iOS ⼯工程師如何進入?
• Dart 程式語⾔言

• Flutter 的設計典範

• Dart 與 Flutter 的套件/⽣生態系
Dart 程式語⾔言
Dart 程式語⾔言
• 這年年頭的 OO 語⾔言其實都差不多,但還是有少部分差異異

• Dart 除了了可以在 Flutter 執⾏行行以外,也可以編譯成 JS 在網
⾴頁使⽤用,也可以單獨在 Dart VM 執⾏行行

• 所以 Dart 可以寫單獨的 CLI 程式,在 server side 執⾏行行

• Dart 在網⾴頁上可以搭配 Angular 使⽤用…不過這年年頭好像寫
Angular 的⼈人比較少
單獨安裝 Dart
• ⽤用 homebrew 安裝 dart

• brew install dart

• 同時建議安裝 stagehand,Dart 的新專案產⽣生器

• pub global activate stagehand
開始新專案
Swift Package Manager
$swift package init

init 後可接 --type

empty|library|executable|
system-module

Dart
$stagehand [project type]

Project type 可接

• console-full

• package-simple

• server-shelf

• web-angular…
Dependency
iOS/Swift 開發
• 可使⽤用 SPM package 或是
Cocoapods

• Cocoapods 可在 https://
cocoapods.org/ 查詢

• SPM Package 的
Dependency 設定寫在
Package.swift 中

• 使⽤用 swift package update
更更新
Dart
• 使⽤用 pub

• 可在 https://
pub.dartlang.org/ 查詢

• Dependency 設定寫在
pubspec.yaml 中

• ⽤用 pub get 指令更更新
變數、常數
Swift
var -> 可以變動

let -> 不可變動
Dart
var -> 可以變動

final -> 不可變動

const -> 全域的常數
Class
Swift
class Sample {

var x:Int

init (x: Int) {

self.x = x

}

func someMethod() {

self.hi()

}

}

var sample = Sample(x: 1)
Dart
class Sample {

int x = 0;

Sample(this.x) {

}

someMethod() {

this.hi();

}

}

Sample sample = new
Sample(1);
字串串格式
Swift Package Manager
var x = “1 + 1 = ( 1 + 1)”

print(x)
Dart
String x = “1 + 1 = ${ 1 + 1}”;

print(x);
匿名函式
Swift
{ x in …

}

或

{ $0.doSomething() }
Dart
(int x) {

…

}

或寫成單⾏行行

(x) => doSomething(x);
匿名函式
Swift
class MyClass {

	 var f: ((Int)->Int)?

}

var x = MyClass()

x.f = { $0 + 1 }

print("(x.f!(2))"

// Swift 也可以⽤用 typealias
Dart
// ⼀一定要⽤用 typedef

typedef int Call(int);

class MyClass {

Call f;

}

main() {

var x = new MyClass();

x.f = (i) => i + 1;

print(x.f(2));

}
Nullability
Swift
必須要將任何變數的形態設定
為 optional,才可以將變數指
向 nil。
Dart
可以將任意變數指向 null,任
何變數⼀一開始不給予值也是
null,但是可以使⽤用與 Swift
相同的 ?? 語法判斷是否是
null。
Callback
Swift
• URLSessionTask 使⽤用
Closure 處理理 callback

• 加裝 promise kit 等套件之
後,可以使⽤用 promise 語
法
Dart
• import ‘dart/async’;

• 使⽤用 Future 物件

• 可使⽤用 Promise 語法或是
async/await
Delegate?
• 在 ObjC/Swift 中⼤大量量使⽤用 Delegate Pattern

• 在 Dart 中改⽤用 Stream Controller

• Stream Controller 可以⽤用來來發送事件,Listener 則監聽從
Stream Controller 發送的事件
Stream Controller in Dart
import 'dart:async';

class MyClass {

StreamController controller = new StreamController.broadcast();

Stream get didSomething = controller.stream;

someMethod() {

this.controller.add(‘Test’);

}

}

MyClass obj = new MyClass();

obj.didSomething.listen( (String s) {

print(s);

});
Dart 也有叫做 Delegate 的東⻄西
• 不是每個叫做 Delegate 的東⻄西都是同樣意思

• ObjC/Swift 的 Delegate 通常⽤用在 Model 或 View 發⽣生改變
的時候,⽤用來來通知 Controller,也就是 Controller 是 Model
或 View 的 Delegate

• Dart 上也可以實作 ObjC/Swift 的 delegate,⽤用 abstract 代
替 protocol…但好像沒有⼈人這麼做
Dart 也有叫做 Delegate 的東⻄西
• Dart 的 Delegate 則指的是某個物件要使⽤用的規則,比較是
⼀一種純 Model 物件

• Dart 的 Delegate 很像 CocoaTouch 中 UICollectionView
與 UICollectionViewLayout 的關係

• 像是 Flutter 的 GirdView 的 delegate,就是 Grid 有幾⾏行行、
間距多少…等邏輯
Notification Center?
• 有類似的東⻄西 https://github.com/stevenroose/dart-events

• 另外也有⼈人在 Flutter 上實作 redux https://
pub.dartlang.org/packages/flutter_redux
Flutter
這個框架的設計概念念跟你
以前寫過的東⻄西差很多喔
Widget Model/Builder
• iOS 上畫⾯面主要由 View Controller/View 組成,View Controller
管理理⼀一個 view property,然後在上⾯面新增/移除 subview

• Flutter 的畫⾯面是由 Widget 組成,每個 Widget ⼜又都是⼀一個
builder,build 出這個 Widget 下有哪些內部的 Widget

• …其實 Flutter 裡頭什什麼都是 Widget

• Build 出的 Widget 再交給 Flutter 的 Renderer 給 render 成畫⾯面

• 某⽅方⾯面來來看,Flutter 的架構中比較沒有明確的 MVC 之分,⼀一個
Widget 像是扮演了了 Controller 與 View 的⾓角⾊色,但本質上
Widget 卻⼜又是 Model…
Widget Model/Builder
• Widget 在 Build 出底下的 Widget 之後,就無法再改動,
要改變畫⾯面,就要再 Build ⼀一次,Build 出另外⼀一份 Widget

• ⼀一個 widget 有點像是 Web 開發的 Virtual DOM,但比較不
同的時,Flutter 的 widget model 沒有做 HTML Tag/CSS
分離,⽽而是 widget 本⾝身就帶有樣式的性質

• Widget 做的事情也超過 DOM Element,Layout/動畫/
對比 iOS 開發看 Widget
• iOS 上,每個 view 的重繪,是在對 UIView 呼叫
setNeedDisplay 之後,才會呼叫 UIView 的 drawRect: 或
是 CALayer 的 drawInContext: 重繪

• 更更新⼀一個 widget 似乎有點類似:對 Widget 的 State 呼叫
setState() 後,才會重新 build 出⼀一份 widget ,由這份
widget render 出新的畫⾯面

• 也有點像是在 Vue.js 裡頭對某個 component 呼叫
$nextTick()
Widget 有兩兩種
• Stateless Widget:Widget build 出來來之後就不會改變內部
widget,往往⽤用在最⼤大或最⼩小的元件。最⼤大如整個 App 的
框架(MaterialApp Class)最⼩小的元件如⽂文字框(Text
Class)

• Stateful Widget:會改變狀狀態的 widget,負責掌管⼀一個
State 屬性,在 State 中再負責 build 出 widget。⼤大多時間
我們會寫這類的 Widget。
App:第⼀一個 Widget
void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {

// This widget is the root of your application.

@override

Widget build(BuildContext context) {

return new MaterialApp(

title: ‘My App',

theme: new ThemeData(

primarySwatch: Colors.blue,

),

home: new HomePage(title: ‘Home Page’),

);

}

} // 然後我們就可以繼續寫 HomePage class
Widget 有兩兩種
• 在前⾯面的範例例中

• MyApp 是 Stateless Widget

• Home Page 是 Stateful Widget
Decorator 風格
• 在其他框架中的元件屬性,在 Flutter 中則往往設計成被另
外⼀一個 Widget 包裝起來來

• ⼀一堆⽂文字置中: Center -> Column -> [Text, Text]

• 圖形放在圓框裡:Box Decoration -> Image
⼀一堆⽂文字置中
把圖放在圓框裡頭
處理理觸控事件
• 有些元件本⾝身就有 onTap,可以傳入匿名函式或某個物件
的 method

• 所有的物件都可以被包在 GestureDetector 當中
Navigation
Widget 不⼀一定是 UI Element
什什麼時候去呼叫 Web API?
• 可以使⽤用 Future Block

• 或是在 initState 的時候,呼叫 Web API call,在 Promise
結束的時候呼叫 setState() 更更新畫⾯面

• 如果要做⾴頁⾯面 retry 的話,後⾯面這種作法可能比較好
Widget 深度往往深得亂七八糟…
Scaffold
• ⼀一個 App 最常⽤用的框架

• AppBar -> 類似 iOS NavigationBar

• Drawer -> 漢堡選單

• Floating Action Button -> Material Design 的特殊 UI

• Bottom Navigation Bar -> 類似 iOS 的 TabBar
建構畫⾯面的流程
• 從 Home Page 建置 Scaffold

• 根據各種⾏行行為,更更換 Scaffold 中的 body
⼀一些眉眉⾓角⾓角
• ListView 與 Grid View 只能單個 Section,如果想要多
Section 的 ListView 或 GridView,要改⽤用
CustomScrollView

• CustomScrollView 的 children 得要⽤用 SliverListView 以及
SliverGridView,⽽而不是直接把 ListView 或 GridView 放進
去
Flutter Plug-in
Flutter Plug-in
• 有些跟平台有關的事情,Flutter 不直接⽀支援

• 可以⾃自⼰己撰寫與平台橋接的程式(Platform Channel)
https://flutter.io/platform-channels/

• 或是安裝已經有⼈人包好的 Flutter Plug-in
Open URL
• 在 iOS 上可以呼叫 UIApplication 的 openURL: 以及
canOpenURL:

• Flutter 上要安裝 url_launcher https://pub.dartlang.org/
packages/url_launcher

• 改寫 pubspec.yaml 然後⽤用 flutter packages get 更更新
dependencies
學習資源
• Flutter 原廠⽂文件 https://flutter.io/docs/

• Coding with Flutter https://medium.com/coding-with-
flutter

• Google IO 2018 其實沒講什什麼東⻄西

給 iOS 工程師的 Flutter 開發

  • 1.
    給 iOS ⼯工程師的 Flutter開發 zonble zonble@gmail.com
  • 2.
    Flutter • https://flutter.io • ⼀一個寄宿在⽬目前iOS、Android 平台上的新平台 • 是設計給 Google 未來來作業系統 Fuchsia 的應⽤用程式開發層 • Dart VM + Skia Render 引擎 • 在 iOS/Android App 中包入 Flutter Framework 後,執⾏行行 Dart code,同⼀一個 App 在不同平台可以 render 出相同的效果 • 可以與 ObjC/Swift/Java/Kotlin 橋接 • 重新發明 Flash?
  • 3.
    ⽤用 Flutter 可能有什什麼好處? •以⽬目前的執⾏行行效能與完成度來來看,似乎不能不管 • 如果同時需要開發 iOS/Android,可以⼤大量量共⽤用程式碼 • iOS/Android 上可以 Render 出⼀一樣的畫⾯面,設計師可以只 需要做⼀一套設計 • 現在就先投資未來來的 Google 作業系統,以及 Flutter 還可 能移植到 Windows/Mac/瀏覽器執⾏行行的可能
  • 4.
    ⽤用 Flutter 會犧牲什什麼 •還不⽀支援⼀一些 iPhone 的特殊功能,如 3D Touch • 不過你的 App 本來來也就沒在⽀支援 3D Touch • 犧牲跟 macOS/tvOS/watchOS 共⽤用程式碼的機會 • 不過你本來來也沒在⽀支援 • 好的 Dart 語⾔言的⼯工程師不好找 • 不過反正你本來來也找不到好的 ObjC/Swift/Java/Kotlin ⼯工 程師
  • 5.
    ⽤用 Flutter 會犧牲什什麼 •在 iOS 上由於⽤用的不是 UIKit 元件,看起來來會比較像 Google Photo 的感覺,⽽而不像「很 Apple」的 App • 無法使⽤用 XCTest 測試 • 上線後,從 iOS 的 crash log 中看不出 Dart 程式的問題 • 專案會與 Firebase 變得更更緊密,因為現在供 Flutter 使⽤用的 BaaS、Analytics…都只有 Firebase 這個選擇
  • 6.
    使⽤用 Flutter 的挑戰 •Flutter 無法使⽤用⼀一些平台專屬功能,⽽而可能需要寫與該平 台橋接的程式,所以現階段還是得懂⼀一定的 iOS/Android 開發 • 哪些部分⽤用 Flutter 寫,哪些寫在 iOS/Android 橋接端,非 常挑戰 App 架構的能⼒力力
  • 7.
    安裝 • 先裝好 Xcode以及 Android Studio • 去 https://flutter.io/setup-macos/ 下載 zip 檔解壓 • 執⾏行行 flutter doctor 看看少了了什什麼 • ⽤用 homebrew 裝 ideviceinstaller 以及 ios-deploy • IDE 可⽤用 Android Studio 或 VSCode
  • 8.
    iOS ⼯工程師如何進入? • Dart程式語⾔言 • Flutter 的設計典範 • Dart 與 Flutter 的套件/⽣生態系
  • 9.
  • 10.
    Dart 程式語⾔言 • 這年年頭的OO 語⾔言其實都差不多,但還是有少部分差異異 • Dart 除了了可以在 Flutter 執⾏行行以外,也可以編譯成 JS 在網 ⾴頁使⽤用,也可以單獨在 Dart VM 執⾏行行 • 所以 Dart 可以寫單獨的 CLI 程式,在 server side 執⾏行行 • Dart 在網⾴頁上可以搭配 Angular 使⽤用…不過這年年頭好像寫 Angular 的⼈人比較少
  • 11.
    單獨安裝 Dart • ⽤用homebrew 安裝 dart • brew install dart • 同時建議安裝 stagehand,Dart 的新專案產⽣生器 • pub global activate stagehand
  • 12.
    開始新專案 Swift Package Manager $swiftpackage init init 後可接 --type empty|library|executable| system-module Dart $stagehand [project type] Project type 可接 • console-full • package-simple • server-shelf • web-angular…
  • 13.
    Dependency iOS/Swift 開發 • 可使⽤用SPM package 或是 Cocoapods • Cocoapods 可在 https:// cocoapods.org/ 查詢 • SPM Package 的 Dependency 設定寫在 Package.swift 中 • 使⽤用 swift package update 更更新 Dart • 使⽤用 pub • 可在 https:// pub.dartlang.org/ 查詢 • Dependency 設定寫在 pubspec.yaml 中 • ⽤用 pub get 指令更更新
  • 14.
    變數、常數 Swift var -> 可以變動 let-> 不可變動 Dart var -> 可以變動 final -> 不可變動 const -> 全域的常數
  • 15.
    Class Swift class Sample { varx:Int init (x: Int) { self.x = x
 } func someMethod() { self.hi()
 }
 } var sample = Sample(x: 1) Dart class Sample { int x = 0; Sample(this.x) {
 } someMethod() { this.hi();
 }
 } Sample sample = new Sample(1);
  • 16.
    字串串格式 Swift Package Manager varx = “1 + 1 = ( 1 + 1)” print(x) Dart String x = “1 + 1 = ${ 1 + 1}”; print(x);
  • 17.
    匿名函式 Swift { x in… } 或 { $0.doSomething() } Dart (int x) { …
 } 或寫成單⾏行行 (x) => doSomething(x);
  • 18.
    匿名函式 Swift class MyClass { var f: ((Int)->Int)? } var x = MyClass() x.f = { $0 + 1 } print("(x.f!(2))" // Swift 也可以⽤用 typealias Dart // ⼀一定要⽤用 typedef typedef int Call(int); class MyClass { Call f; } main() { var x = new MyClass(); x.f = (i) => i + 1; print(x.f(2)); }
  • 19.
    Nullability Swift 必須要將任何變數的形態設定 為 optional,才可以將變數指 向 nil。 Dart 可以將任意變數指向null,任 何變數⼀一開始不給予值也是 null,但是可以使⽤用與 Swift 相同的 ?? 語法判斷是否是 null。
  • 20.
    Callback Swift • URLSessionTask 使⽤用 Closure處理理 callback • 加裝 promise kit 等套件之 後,可以使⽤用 promise 語 法 Dart • import ‘dart/async’; • 使⽤用 Future 物件 • 可使⽤用 Promise 語法或是 async/await
  • 21.
    Delegate? • 在 ObjC/Swift中⼤大量量使⽤用 Delegate Pattern • 在 Dart 中改⽤用 Stream Controller • Stream Controller 可以⽤用來來發送事件,Listener 則監聽從 Stream Controller 發送的事件
  • 22.
    Stream Controller inDart import 'dart:async'; class MyClass { StreamController controller = new StreamController.broadcast(); Stream get didSomething = controller.stream; someMethod() { this.controller.add(‘Test’);
 }
 } MyClass obj = new MyClass(); obj.didSomething.listen( (String s) { print(s); });
  • 23.
    Dart 也有叫做 Delegate的東⻄西 • 不是每個叫做 Delegate 的東⻄西都是同樣意思 • ObjC/Swift 的 Delegate 通常⽤用在 Model 或 View 發⽣生改變 的時候,⽤用來來通知 Controller,也就是 Controller 是 Model 或 View 的 Delegate • Dart 上也可以實作 ObjC/Swift 的 delegate,⽤用 abstract 代 替 protocol…但好像沒有⼈人這麼做
  • 24.
    Dart 也有叫做 Delegate的東⻄西 • Dart 的 Delegate 則指的是某個物件要使⽤用的規則,比較是 ⼀一種純 Model 物件 • Dart 的 Delegate 很像 CocoaTouch 中 UICollectionView 與 UICollectionViewLayout 的關係 • 像是 Flutter 的 GirdView 的 delegate,就是 Grid 有幾⾏行行、 間距多少…等邏輯
  • 25.
    Notification Center? • 有類似的東⻄西https://github.com/stevenroose/dart-events • 另外也有⼈人在 Flutter 上實作 redux https:// pub.dartlang.org/packages/flutter_redux
  • 26.
  • 27.
  • 28.
    Widget Model/Builder • iOS上畫⾯面主要由 View Controller/View 組成,View Controller 管理理⼀一個 view property,然後在上⾯面新增/移除 subview • Flutter 的畫⾯面是由 Widget 組成,每個 Widget ⼜又都是⼀一個 builder,build 出這個 Widget 下有哪些內部的 Widget • …其實 Flutter 裡頭什什麼都是 Widget • Build 出的 Widget 再交給 Flutter 的 Renderer 給 render 成畫⾯面 • 某⽅方⾯面來來看,Flutter 的架構中比較沒有明確的 MVC 之分,⼀一個 Widget 像是扮演了了 Controller 與 View 的⾓角⾊色,但本質上 Widget 卻⼜又是 Model…
  • 29.
    Widget Model/Builder • Widget在 Build 出底下的 Widget 之後,就無法再改動, 要改變畫⾯面,就要再 Build ⼀一次,Build 出另外⼀一份 Widget • ⼀一個 widget 有點像是 Web 開發的 Virtual DOM,但比較不 同的時,Flutter 的 widget model 沒有做 HTML Tag/CSS 分離,⽽而是 widget 本⾝身就帶有樣式的性質 • Widget 做的事情也超過 DOM Element,Layout/動畫/
  • 30.
    對比 iOS 開發看Widget • iOS 上,每個 view 的重繪,是在對 UIView 呼叫 setNeedDisplay 之後,才會呼叫 UIView 的 drawRect: 或 是 CALayer 的 drawInContext: 重繪 • 更更新⼀一個 widget 似乎有點類似:對 Widget 的 State 呼叫 setState() 後,才會重新 build 出⼀一份 widget ,由這份 widget render 出新的畫⾯面 • 也有點像是在 Vue.js 裡頭對某個 component 呼叫 $nextTick()
  • 31.
    Widget 有兩兩種 • StatelessWidget:Widget build 出來來之後就不會改變內部 widget,往往⽤用在最⼤大或最⼩小的元件。最⼤大如整個 App 的 框架(MaterialApp Class)最⼩小的元件如⽂文字框(Text Class) • Stateful Widget:會改變狀狀態的 widget,負責掌管⼀一個 State 屬性,在 State 中再負責 build 出 widget。⼤大多時間 我們會寫這類的 Widget。
  • 32.
    App:第⼀一個 Widget void main()=> runApp(new MyApp()); class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { return new MaterialApp( title: ‘My App', theme: new ThemeData( primarySwatch: Colors.blue, ), home: new HomePage(title: ‘Home Page’), ); } } // 然後我們就可以繼續寫 HomePage class
  • 33.
    Widget 有兩兩種 • 在前⾯面的範例例中 •MyApp 是 Stateless Widget • Home Page 是 Stateful Widget
  • 34.
    Decorator 風格 • 在其他框架中的元件屬性,在Flutter 中則往往設計成被另 外⼀一個 Widget 包裝起來來 • ⼀一堆⽂文字置中: Center -> Column -> [Text, Text] • 圖形放在圓框裡:Box Decoration -> Image
  • 35.
  • 37.
  • 39.
  • 40.
  • 41.
  • 42.
    什什麼時候去呼叫 Web API? •可以使⽤用 Future Block • 或是在 initState 的時候,呼叫 Web API call,在 Promise 結束的時候呼叫 setState() 更更新畫⾯面 • 如果要做⾴頁⾯面 retry 的話,後⾯面這種作法可能比較好
  • 43.
  • 44.
    Scaffold • ⼀一個 App最常⽤用的框架 • AppBar -> 類似 iOS NavigationBar • Drawer -> 漢堡選單 • Floating Action Button -> Material Design 的特殊 UI • Bottom Navigation Bar -> 類似 iOS 的 TabBar
  • 45.
    建構畫⾯面的流程 • 從 HomePage 建置 Scaffold • 根據各種⾏行行為,更更換 Scaffold 中的 body
  • 46.
    ⼀一些眉眉⾓角⾓角 • ListView 與Grid View 只能單個 Section,如果想要多 Section 的 ListView 或 GridView,要改⽤用 CustomScrollView • CustomScrollView 的 children 得要⽤用 SliverListView 以及 SliverGridView,⽽而不是直接把 ListView 或 GridView 放進 去
  • 47.
  • 48.
    Flutter Plug-in • 有些跟平台有關的事情,Flutter不直接⽀支援 • 可以⾃自⼰己撰寫與平台橋接的程式(Platform Channel) https://flutter.io/platform-channels/ • 或是安裝已經有⼈人包好的 Flutter Plug-in
  • 49.
    Open URL • 在iOS 上可以呼叫 UIApplication 的 openURL: 以及 canOpenURL: • Flutter 上要安裝 url_launcher https://pub.dartlang.org/ packages/url_launcher • 改寫 pubspec.yaml 然後⽤用 flutter packages get 更更新 dependencies
  • 50.
    學習資源 • Flutter 原廠⽂文件https://flutter.io/docs/ • Coding with Flutter https://medium.com/coding-with- flutter • Google IO 2018 其實沒講什什麼東⻄西