0%

【文章內容使用 Gemini 1.5 Pro 自動產生】

展示如何使用 Flutter 開發定制 UI 的參考應用程式

我們對 Flutter 的願景是為您提供一個空白畫布,讓您可以設計和繪製美麗的應用程式,不受限制。最近,我們與 gskinner 的出色團隊合作,透過建立一個新的行動應用程式 Wonderous,使這一願景成為現實。Wonderous 使用 Flutter 建立了一個高度表現力的使用者介面,該介面針對行動外觀因素量身定制,並且不符合標準設計系統。相反,Wonderous 實現了其設計師的創意願景。

Wonderous 應用程式的螢幕截圖

在開發 Wonderous 時,我們心中有幾個目標:

  1. 建立一個有趣且有用的應用程式。 Wonderous 不僅僅是一個示範,它是一個功能齊全的應用程式,允許使用者透過探索世界奇觀來探索歷史、藝術和文化的交匯點。在許多人難以旅行的時代,Wonderous 利用令人驚嘆的插圖和增強的動畫,直接在您的設備上讓這些景點的奇蹟栩栩如生。
  2. 展示高品質的使用者體驗。 我們希望 Wonderous 的品質能與系統框架中的任何應用程式相媲美。Wonderous 以其量身定制的富有想像力的設計吸引觀眾,同時使用熟悉的手勢和行為來確保無縫的使用者體驗。
  3. 建立一個用於測試和基準測試的應用程式。 我們已經使用 Wonderous 來測試 Impeller,這個新的渲染引擎現在可以在 iOS 上預覽。到目前為止,我們對結果感到滿意,這有助於驗證我們對改善效能的假設。從 Apple App Store 下載的應用程式版本使用 Impeller,我們渴望看到它在更廣泛的 iOS 設備上的實際條件下是如何執行的。
  4. 提供一個示例的開放原始碼參考應用程式,展示最佳實務。 Wonderous 程式碼 展示了自訂設計、引人入勝的互動和新穎動畫的開發最佳實務 - 所有這些都將無障礙列為首要考量。
  5. 建立一個用於學習材料和文件資源的來源。 在接下來的幾週內,gskinner 團隊將發佈更多關於 Wonderous 的內容,包括如何建立動畫、如何整合無障礙功能以及應用程式效能的最佳實務。敬請期待!

從 Apple App Store 或 Google Play 商店 [下載 Wonderous](http://wonderous.app) 後,您可能想探索以下幾個特點:

  • 沒有 Flutter 可能很困難的轉場,這些轉場在奇觀之間左右滑動時特別明顯。
  • 當您在全球時間軸中移動時,獨特的捲軸模式。
  • 與 Wonderous 設計系統相符的定制按鈕和圖示。

我們很高興與全世界分享 Wonderous,讓我們知道您的想法!


Wonderous:使用 Flutter 探索世界 最初發表在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動產生】

Flutter 3.3 的新功能

文字處理、效能改進和更多令人興奮的更新!

歡迎來到 Flutter 3.3!僅僅三個月前,我們宣布了 Flutter 3,這是一個重大的里程碑,其中包含對所有平台的穩定支援!好消息是,自此重大版本發佈以來,其發展勢頭並沒有減弱。自 Flutter 3 發佈以來,Flutter 已合併了 5,687 個 Pull Request。

此版本為 Flutter 網頁、桌面、文字處理改進和效能方面帶來了更新 - 還有更多!

我們還將為 go_router 套件、DevTools 和 VS Code 擴展引入令人興奮的更新。請继续阅读以了解更多。

架構

全域選取

到目前為止,Flutter 網頁應用程式在嘗試選取文字時沒有與預期行為相符。像 Flutter 應用程式一樣,原生網頁應用程式由元素樹組成。在傳統的網頁應用程式中,您可以使用單個掃描手勢選取多個網頁元素,這在 Flutter 網頁應用程式中無法輕鬆完成。

今天,一切都改變了!隨著 SelectableArea Widget 的引入,SelectableArea Widget 的任何子元素都將免費啟用選取功能!

若要利用這個強大的新功能,只需將您的路徑主體(例如 Scaffold)用 SelectableArea Widget 包裹,然後讓 Flutter 完成其餘工作。

若要更全面地深入了解這個強大的新功能,請訪問 SelectableArea API 頁面。

觸控板輸入

Flutter 3.3 為觸控板輸入提供了增強的支援。這不僅提供了更豐富、更流暢的控制,而且在某些情況下還減少了誤解。要查看這種誤解的範例,請查看 Flutter 食譜 中的 拖動 UI 元素 頁面。捲動到頁面底部以到達 DartPad 實例,並執行以下步驟:

  1. 調整視窗大小,使上部顯示一個捲軸
  2. 將滑鼠懸停在上部
  3. 使用觸控板捲軸
  4. 在安裝 Flutter 3.3 之前,在觸控板上捲軸會拖動項目,因為 Flutter 在發送模擬的通用事件
  5. 安裝 Flutter 3.3 後,在觸控板上捲軸會正確地捲軸列表,因為 Flutter 在傳送「捲軸」手勢,該手勢不被卡片識別,但被捲軸視圖識別

如需了解更多資訊,請查看 Flutter 觸控板手勢 設計文件以及 GitHub 上的以下 PR:

Scribble

感謝社群成員 fbcouch 的出色貢獻,Flutter 現在支援在 iPadOS 上使用 Apple Pencil 的 Scribble 手寫輸入。此功能在 CupertinoTextField、TextField 和 EditableText 中預設啟用。若要為您的最終使用者啟用此功能,只需升級到 Flutter 3.3 即可。

文字輸入

為了改進對富文本編輯的支援,此版本引入了從平台的 TextInputPlugin 接收細緻的文字更新的能力。以前,TextInputClient 僅在沒有舊版本和新版本之間的差異的情況下傳送新的編輯狀態,TextEditingDeltas 和 DeltaTextInputClient 填補了此資訊空白。能夠存取這些差異允許您建立一個帶有樣式範圍的輸入欄位,這些範圍會隨著您打字而伸縮。若要了解更多資訊,請查看 富文本編輯器演示

Material Design 3

Flutter 團隊繼續將更多 Material Design 3 組件遷移到 Flutter。此版本包含對 IconButtonChips 以及 AppBar 的大型和中型變化的更新。

若要監控 Material Design 3 遷移的進度,請查看 GitHub 上的 將 Material 3 帶入 Flutter

IconButton

Chip

中型和大型 AppBar

桌面

Windows

以前,Windows 桌面應用程式的版本由特定於 Windows 應用程式的檔案設定。這種行為與其他平台設定其版本的方式不一致。

Windows 桌面應用程式版本現在可以從您的專案 pubspec.yaml 檔案和構建參數設定。這使得為您的最終使用者啟用自動更新變得更加容易,以便在推送應用程式更新時獲得最新和最棒的更新。

如需有關設定應用程式版本的更多資訊,請按照 docs.flutter.dev 上的文件和 遷移指南 進行操作。在 Flutter 3.3 之前建立的專案需要更新才能獲得此功能。

套件

go_router

在設計具有複雜導航需求的應用程式時,事情可能會變得非常難以理解。為了擴展 Flutter 的原生導航 API,團隊發佈了 go_router 套件的新版本,使設計跨行動、桌面和網頁運作的路由邏輯變得更加簡單。

由 Flutter 團隊維護的 go_router 套件通過提供宣告式、基於 URL 的 API 來簡化路由,使導航和處理深層連結變得更加容易。最新版本 (4.3) 使應用程式能夠使用異步程式碼進行重定向,並包含 遷移指南 中描述的其他重大變更。

如需了解更多資訊,請查看 docs.flutter.dev 上的 導航和路由 頁面。

VS Code 擴展增強功能

Visual Studio Code 的 Flutter 擴展包含多項更新,包括為加入相依項提供的改進。您現在可以使用 Dart: Add Dependency 一步加入多個以逗號分隔的相依項。

您可以閱讀自上次 Flutter 穩定版本發佈以來進行的 Visual Studio Code 擴展增強功能資訊:

Flutter DevTools 更新

自上次穩定 Flutter 版本發佈以來,DevTools 進行了多項更新,包括對資料顯示表格的 UX 和效能改進,以實現更快、更少抖動的大型事件列表捲軸 (#4175)。

若要查看自 Flutter 3.0 以來的完整更新列表,請查看此處的個別公告:

效能

柵格快取改進

此版本通過消除複製和減少 Dart 垃圾收集 (GC) 壓力來提高從資產載入圖片的效能。以前,在載入資產圖片時,ImageProvider API 需要將壓縮資料複製多個次。首先,在打開資產並將其作為類型化資料陣列公開給 Dart 時,它被複製到原生堆中。然後,在將該類型化資料陣列複製到 ui.ImmutableBuffer 的內部儲存器時,再次進行複製。

隨著 ui.ImmutableBuffer.fromAsset 的加入,壓縮圖片位元組可以直接載入到用於解碼的結構中。這種方法 需要對 ImageProviders 的位元組載入管道進行更改。這個過程速度也更快,因为它绕过了之前基于方法通道的加载器需要的一些额外的调度开销。特别是,在我们的微基准测试中,图片加载时间提高了近 2 倍。

如需了解更多資訊和遷移指南,請查看 docs.flutter.dev 上的 加入 ImageProvider.loadBuffer

穩定性

iOS 指標壓縮已停用

在 2.10 穩定版本中,我們在 iOS 上啟用了 Dart 的 指標壓縮優化。但是,GitHub 上的 Yeatse 提醒我們 優化的意外後果。Dart 的指標壓縮通過為 Dart 的堆預留一個大型虛擬記憶體區域來工作。由於 iOS 上允許的總虛擬記憶體分配小於其他平台,因此這種大型預留減少了其他組件(例如 Flutter 外掛)為預留自己的記憶體而可用的記憶體量。

雖然停用指標壓縮會增加 Dart 物件佔用的記憶體,但它也會增加 Flutter 應用程式的非 Dart 部分可用的記憶體,總體而言這更可取。

Apple 提供了一個授權,可以增加應用程式允許的最大虛擬記憶體分配,但是此授權僅在較新的 iOS 版本上支援,並且在運行 Flutter 仍然支援的 iOS 版本的設備上不起作用。當我們能夠在所有地方使用此授權時,我們打算重新審查此優化。

API 改進

PlatformDispatcher.onError

在之前的版本中,您必須手動配置自訂區域才能捕獲應用程式的所有異常和錯誤。但是,自訂區域對 Dart 核心函式庫中的許多優化不利,這會減慢應用程式啟動時間。在此版本中,而不是使用自訂區域,您應通過設定 PlatformDispatcher.onError 回調來捕獲所有錯誤和異常。如需了解更多資訊,請查看 docs.flutter.dev 上更新的 在 Flutter 中處理錯誤 頁面。

FragmentProgram 變更

在應用程式的 pubspec.yaml 檔案的 shaders: 區段下編寫的 GLSL 中的片段著色器現在將自動編譯成引擎理解的正確格式,並作為資產與應用程式捆綁在一起。由於此更改,您將不再需要使用第三方工具手動編譯著色器。將來,您應將引擎的 FragmentProgram API 視為僅接受 Flutter 構建工具的輸出。這還不是現在的情況,但此更改計劃在未來的版本中進行,如 FragmentProgram API 支援改進 設計文件中所述。

要查看此更改的範例,請參閱此 Flutter 著色器範例

分數翻譯

以前,Flutter 引擎始終將合成圖層對齊到精確的像素邊界,因為這會提高舊款 (32 位) iPhone 模型的渲染效能。自添加桌面支援以來,我們注意到這導致了可觀察到的捕捉行為,因為螢幕設備像素比率通常要低得多。例如,在低 DPR 螢幕上,工具提示在淡入時會看到明顯的捕捉。在確定此像素捕捉對於更新版 iPhone 模型的效能不再必要之後,我們從 Flutter 引擎中刪除了此像素捕捉 以提高桌面保真度。此外,我們還發現,刪除此像素捕捉使我們的一些黃金圖片測試穩定下來,這些測試會隨著微小的髮絲渲染差異而頻繁變化。

支援平台的更改

32 位 iOS 已棄用

正如我們之前在 3.0 穩定版本中宣布的那樣,由於使用率下降,該版本是 最後一個支援 32 位 iOS 設備和 iOS 版本 9 和 10 的版本。此更改會影響 iPhone 4S、iPhone 5、iPhone 5C 以及第二代、第三代和第四代 iPad 設備。Flutter 的 3.3 穩定版本和所有後續穩定版本不再支援 32 位 iOS 設備和 iOS 版本 9 和 10。這意味著針對 Flutter 3.3 和更高版本構建的應用程式將無法在這些設備上運行。

逐步淘汰 macOS 10.11 和 10.12

在 2022 年第四季度的穩定版本中,我們預計將放棄對 macOS 版本 10.11 和 10.12 的支援。這意味著從那時起針對穩定 Flutter SDK 構建的應用程式將不再在這兩個版本上運行,Flutter 支援的最低 macOS 版本將提高到 10.13 High Sierra。

Bitcode 已棄用

Bitcode 將不再被接受用於即將推出的 Xcode 14 版本中的 iOS 應用程式提交,並且啟用了 Bitcode 的專案將在此版本的 Xcode 中發出構建警告。鑑於此,Flutter 將在未來的穩定版本中放棄對 Bitcode 的支援。

預設情況下,Flutter 應用程式沒有啟用 Bitcode,我們預計這不會影響許多開發人員。但是,如果您在 Xcode 專案中手動啟用了 Bitcode,請在升級到 Xcode 14 後立即停用它。您可以通過打開 ios/Runner.xcworkspace 並將構建設定 Enable Bitcode 設定為 No 來實現這一點。應用程式內新增開發人員應在主機 Xcode 專案中停用它。

請參閱 Apple 的文件 了解有關 Bitcode 分佈的更多資訊。

總結

正如我們一直所說,Google 的 Flutter 團隊非常感謝社群為使 Flutter 變得如此出色所付出的辛勤工作!我們期待繼續迭代已完成的工作,重點關注最重要的內容 - 那就是大家!


Flutter 3.3 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

http://creativecommons.org/licenses/by/4.0/

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

Dart 2.18:Objective-C 與 Swift 互通性

Dart 2.18 現已推出。此版本預覽了 Objective-C 和 Swift 互通性,以及基於此互通性構建的新 iOS/macOS 網路套件。它還包含針對泛型函數的改進類型推斷、異步程式碼的效能改進、新的 pub.dev 功能,以及工具和核心函式庫的清理。

最後,我們有最新的空安全遷移狀態數據,以及關於我們邁向完全空安全 Dart 的重要路線圖更新。請閱讀到最後!

將 Dart 引入 Objective-C 與 Swift 互通性

我們在 2020 年預覽了用於調用原生 C API 的 Dart 外部函數介面 (FFI),並於 2021 年 3 月在 Dart 2.12 中發佈。自該版本以來,大量的套件利用此功能與現有的原生 C API 整合。一些例子包括 file_pickerprintingwin32objectboxrealmisartflite_flutterdbus

Dart 團隊希望 Dart 支援與 Dart 運行的平台上的所有主要語言的互通性。Dart 2.18 達到了實現該目標的下一個里程碑。您的 Dart 程式碼可以調用 Objective-C 和 Swift 程式碼,這些程式碼通常用於 macOS 和 iOS 平台上的 API。Dart 在任何應用程式中都支援這種互通機制,從 CLI 應用程式到後端程式碼再到 Flutter UI。

這種新機制利用了 Objective-C 和 Swift 程式碼可以基於 API 綁定作為 C 程式碼公開的事實。Dart API 包裝器生成工具 ffigen 可以從 API 標頭檔建立這些綁定。讓我們來看一個例子。

使用 Objective-C 的時區範例

macOS 有一個用於查詢時區資訊的 API,公開在 NSTimeZone 類別 上。您可以查詢此 API 以獲取使用者已為其設備設定的時區和 UTC 時區偏移量

以下 Objective-C 應用程式範例使用此時區 API 來獲取系統時區和 GMT 偏移量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
@autoreleasepool {
NSTimeZone *timezone = [NSTimeZone systemTimeZone];
NSInteger secondsFromGMT = [timezone secondsFromGMT];
int hoursFromGMT = secondsFromGMT / 3600;

NSLog(@"Timezone name: %@", [timezone name]);
NSLog(@"Timezone offset GMT: %d hours", hoursFromGMT);
}
return 0;
}

該應用程式匯入了 Foundation.h,其中包含 Apple Foundation 函式庫的 API 標頭檔。接下來,在 main 方法內,它從 NSTimeZone 類別調用 systemTimeZone 方法。此方法返回一個 NSTimeZone 實例,其中包含設備上選定的時區。最後,應用程式向控制台輸出兩行,其中包含時區的名稱和以小時為單位的 UTC 偏移量。

如果您運行此應用程式,它應該返回類似以下內容,具體取決於您的位置:

1
2
Timezone name: Europe/Copenhagen
Timezone offset GMT: 2 hours

使用 Dart 的時區範例

讓我們使用新的 Objective-C 互通性在 Dart 中複製此結果。

首先建立一個新的 Dart CLI 應用程式:

1
$ dart create timezones

然後編輯您的 pubspec 檔案以包含 ffigen 設定。此設定指向標頭檔,並列出應該生成包裝器的 Objective-C 介面:

1
2
3
4
5
6
7
8
9
10
ffigen:
name: 'FoundationBindings'
output: 'foundation_bindings.dart'
headers:
entry-points:
- '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSTimeZone.h'
objc-interfaces:
include:
- 'NSTimeZone'
description: 'Bindings to Foundation'

這將為 NSTimeZone.h 中的標頭檔選擇 Objective-C 綁定,並且僅包含 NSTimeZone 介面中的 API。要生成包裝器,請運行 ffigen

1
$ dart run ffigen

此命令建立一個新檔案 foundation_bindings.dart,其中包含一堆生成的 API 綁定。使用此綁定檔案,我們可以編寫我們的 Dart main 方法。此方法反映了 Objective-C 程式碼:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import 'dart:ffi';
import 'dart:io';

import 'package:ffi/ffi.dart';
import 'package:timezones/foundation_bindings.dart';

typedef SystemTimeZoneC = Pointer<NSTimeZone> Function();
typedef SystemTimeZoneDart = Pointer<NSTimeZone> Function();

typedef SecondsFromGMTC = Int64 Function(Pointer<NSTimeZone>);
typedef SecondsFromGMTDart = int Function(Pointer<NSTimeZone>);

typedef GetNameC = Pointer<Utf8> Function(Pointer<NSTimeZone>);
typedef GetNameDart = Pointer<Utf8> Function(Pointer<NSTimeZone>);


void main() {
final dylib = DynamicLibrary.open(Platform.isMacOS ? '/System/Library/Frameworks/Foundation.framework/Versions/Current/Foundation' : 'Foundation');

final systemTimeZonePointer = dylib.lookupFunction<SystemTimeZoneC, SystemTimeZoneDart>('NSTimeZone_systemTimeZone');
final timezone = systemTimeZonePointer();

final secondsFromGMTPointer = dylib.lookupFunction<SecondsFromGMTC, SecondsFromGMTDart>('NSTimeZone_secondsFromGMT');
final secondsFromGMT = secondsFromGMTPointer(timezone);
final hoursFromGMT = secondsFromGMT / 3600;


final getNamePointer = dylib.lookupFunction<GetNameC, GetNameDart>('NSTimeZone_name');
final name = getNamePointer(timezone).toDartString();

print('Timezone name: $name');
print('Timezone offset GMT: $hoursFromGMT hours');
}

就這樣!從今天的 Dart 2.18 開始,此新支援以實驗狀態提供。這增強了 Dart 的通用互通性支援,可以直接調用 macOS 和 iOS API。反過來,這補充了 Flutter 的 Plugin,提供了在任何 Dart 應用程式中都能運作的新支援,並允許您直接從 Dart 程式碼調用 macOS 和 iOS API。

我們歡迎您的回饋。請透過在 GitHub 上的 回饋議題 中評論,讓我們知道哪些有效、哪些可以更改或您遇到的問題。要進一步了解此互通性,請參閱 Objective-C 和 Swift 互通性指南

平台特定的 http 函式庫

Dart 包含一個通用的多平台 http 函式庫。此函式庫允許您編寫程式碼,而無需考慮平台細節。有時,您可能希望編寫特定於特定主機平台網路 API 的程式碼。

例如,Apple 的網路函式庫 NSURLSession 允許指定僅限 WiFi 的網路或需要 VPN。為了支援這些使用案例,我們建立了一個新的網路套件,用於 macOS 和 iOS 平台,cupertino_http。這是建立在上一節提到的新的 Objective-C 互通性之上的。它使用從 Foundation 中 Apple 的網路 API 生成 的大量 API 包裝器。

Cupertino http 函式庫範例

以下範例將 Flutter 應用程式的 http 用戶端設定為在 macOS 和 iOS 上使用 cupertino_http 函式庫,並在其他平台上使用來自 dart:io 的 Dart 常規 http 函式庫:

1
2
3
4
5
6
7
8
9
10
import 'package:cupertino_http/cupertino_http.dart' as cupertino;
import 'package:http/http.dart' as http;

late final http.Client client;

if (Platform.isIOS || Platform.isMacOS) {
client = cupertino.Client();
} else {
client = http.Client();
}

在此初始設定之後,應用程式會在特定用戶端上進行任何後續的網路調用。例如,http get() 請求現在類似於:

1
2
3
4
final url = Uri.parse('https://example.com/whatsit/create');
final response = await client.get(url);
print('Response status: ${response.statusCode}');
print('Response body: ${response.body}');

當您無法使用通用用戶端介面時,您可以使用 cupertino_http 函式庫直接調用 Apple 的網路 API:

1
2
3
4
5
6
7
8
final session = cupertino.cupertinoHttp.NSURLSession.sharedSession();

// Now you can use session to perform network requests such as
// dataTaskWithRequest, dataTaskWithURL, etc
// For example to get data from a URL:
final url = cupertino.cupertinoHttp.NSURL(string: 'www.google.com')!;
// Now use the URL to get data or perform any other NSURLSession task.

多平台應用程式中的平台特定網路

當我們設計此功能時,目標仍然是盡可能保持應用程式的多平台性。為了實現此目標,我們保留了用於基本 http 操作的通用多平台 http API 集,並允許為每個平台設定要使用的網路函式庫。您可以透過使用 package:http Client API 來最大限度地減少您需要編寫的平台特定程式碼的數量。此 API 可以為每個平台進行設定,但以平台獨立的方式使用。

Dart 2.18 提供了對兩個支援 package:http Client API 的平台特定 http 函式庫的實驗性支援:

將通用用戶端 API 與多個 HTTP 實作相結合,為您提供了兩全其美的優勢。您可以獲得平台特定的行為,同時仍然可以從所有平台的單一共享來源集中維護您的應用程式。我們很樂意聽到您對此 GitHub 議題 的回饋。

改進的類型推斷

Dart 使用許多泛型函數。考慮 fold 方法,它將元素的集合簡化為單個值。以下範例計算整數列表的總和:

1
2
3
List<int> numbers = [1, 2, 3];
final sum = numbers.fold(0, (x, y) => x + y);
print('The sum of $numbers is $sum');

在 Dart 2.17 或更早版本中,此方法返回類型錯誤:

1
line 2 • The operator '+' can't be unconditionally invoked because the receiver can be 'null'.

Dart 的類型推斷無法在參數之間傳遞資訊。這導致 x 的類型不確定。要解決潛在的錯誤,您需要指定類型:

1
final sum = numbers.fold(0, (int x, int y) => x + y);

Dart 2.18 改進了類型推斷。之前的範例通過了靜態分析,並且可以推斷 xy 都是非空的整數。此更改允許您編寫更簡潔的 Dart 程式碼,同時保留強類型推斷的完整可靠性屬性。

異步效能改進

此版本的 Dart 改進了 Dart VM 應用異步方法和 async*/sync* 生成器函數的方式。這減少了程式碼大小。在兩個大型內部 Google 應用程式上,我們看到 AOT 快照大小減少了大約 10%。我們還看到微基準測試中的效能有所提高。

這些更改包括其他一些小的行為更改;要進一步了解,請參閱 變更日誌

pub.dev 的改進

與 2.18 版本一起,我們對 pub.dev 套件儲存庫進行了兩項更改。

個人通常在業餘時間維護發佈在 pub.dev 上的套件。這在時間和財務方面都可能付出高昂的代價。為了促進贊助,我們現在在 pubspec 中支援一個新的 funding 標籤,套件發佈者可以使用它來列出一個或多個贊助套件的連結。然後,這些連結會顯示在 pub.dev 的側邊欄中:

要進一步了解,請參閱 pubspec 文件

此外,我們希望鼓勵豐富的開源套件生態系統。為了突出這一點,pub.dev 上的自動套件評分為使用 OSI 批准的許可證 的套件額外獎勵 10 分。

一些重大變更

Dart 非常注重簡潔性和可學習性。在添加新功能時,我們一直在努力保持謹慎的平衡。保持事物簡潔的一種方法是移除使用較少或有更好替代方案的歷史功能和 API。Dart 2.18 清理了此類別中的項目,包括一些較小的重大變更:

  • 我們在 2.18 中完成了過渡。此版本移除了最後兩個已棄用的工具 dart2js(使用 dart compile js)和 dartanalyzer(使用 dart analyze)。
  • 隨著語言版本控制的引入,pub 生成了一個新的解析檔案:.dart_tool/package_config.json。之前的檔案 .packages 使用的格式無法包含版本。我們停止使用 .packages 檔案。如果您有任何 .packages 檔案,您可以將其刪除。
  • 不能使用不擴展 Object 的類別的 Mixin(重大變更 #48167)。這種行為從未被設計過。
  • dart:ioRedirectExceptionuri 屬性已更改為可空(重大變更 #49045)。
  • dart:io 的網路 API 中遵循 SCREAMING_SNAKE 約定的常數已被移除(重大變更 #34218;先前已棄用)。請改用相應的 lowerCamelCase 常數。
  • Dart VM 不再在退出時恢復初始終端設定。更改 Stdin 設定 lineModeechoMode 的程式現在負責在程式退出時恢復設定(重大變更 #45630)。

空安全更新

我們很高興看到自 2020 年 11 月的 Beta 版本和 2021 年 3 月的 Dart 2.12 版本以來,空安全的廣泛使用。

首先,pub.dev 上幾乎所有流行套件的應用程式開發人員都遷移到了空安全。分析顯示,前 250 名中最常用的套件中有 100% 支援空安全,前 1,000 名中最常用的套件中有 98% 支援空安全。

其次,大多數應用程式開發人員都在完全遷移到空安全的程式碼庫中工作。這一點至關重要。Dart 的完整 可靠空安全 在您遷移所有程式碼和所有依賴項(包括傳遞依賴項)之前不會生效。我們正在透過 flutter run 命令的遙測數據來追蹤這一點。

下圖顯示了 flutter run 的不可靠與可靠空安全執行。在引入空安全之前,兩者都沒有。隨後是不可靠空安全的快速增長。隨著應用程式開始遷移到空安全,開發人員進行了部分遷移。有些部分仍然需要遷移。隨著時間的推移,我們看到可靠空安全會話的健康增長。到上個月底,可靠空安全會話的數量是不可靠空安全會話的四倍。我們希望在接下來的幾個季度中,我們將看到可靠空安全方法達到 100%!

空安全路線圖的重要更新

同時支援不可靠和可靠的空安全會增加開銷和複雜性。

首先,Dart 開發人員需要學習和理解兩種模式。每當閱讀一段 Dart 程式碼時,請檢查 語言版本,以查看類型預設是否為非空(Dart 2.12 及更高版本)或可空(Dart 2.11 及更早版本)。

其次,在我們的編譯器和運行時中同時支援兩種模式會減慢 Dart SDK 的發展速度,以支援新功能。

基於不可靠空安全的開銷以及上一節提到的非常積極的採用數據,我們的目標是過渡到僅支援可靠空安全,並停止非空安全和不可靠空安全模式。我們暫定於 2023 年年中發佈此版本。

這意味著將停止支援 Dart 2.11 及更早版本。SDK 約束下限小於 2.12 的 Pubspec 檔案將不再在 Dart 3 及更高版本中解析。在包含語言標記的原始程式碼中,如果設定小於 2.12(例如 // @dart=2.9),則會失敗。

如果您已遷移到可靠空安全,您的程式碼將在 Dart 3 中以完全空安全的方式工作。如果您還沒有遷移,請立即遷移!要進一步了解這些更改,請參閱此 GitHub 議題

總結

對互通性、網路、類型推斷和 pub.dev 的新支援現已推出。要開始使用,您可以直接下載 Dart 2.18 版本,或者將其作為今天的 Flutter 3.3 SDK 版本的一部分嵌入。


Dart 2.18:Objective-C 與 Swift 互通性 最初發佈在 Medium 的 Dart 上,人們在那裡透過醒目顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

了解如何在 Flutter Games 範例中啟用 Crashlytics,讓您更容易偵測和修復遊戲中的問題

Flutter 休閒遊戲工具包 (FCGT) 是一個針對想要建立行動遊戲應用程式的開發人員的入門範本。它已經透過主選單、遊戲關卡、設定畫面、音效、音樂等等進行自訂。除了範本應用程式之外,您也可以下載一個基於此範本的 井字遊戲應用程式

以下螢幕截圖依序顯示開箱即用的主選單、遊戲關卡頁面和設定頁面:

Screenshots of the 3 main screens from the FCGT sample app: Main menu, Select Level & Settings
FCGT 螢幕截圖

FCGT 包含一些在開發您自己的遊戲時很有用的服務整合:Apple Game Center、Google Play Games 服務、Google 行動廣告 SDK 和應用程式內購套件。這些更進階的整合最初是被停用的,因為它們需要您(開發人員)在使用它們之前進行一些設定。如果您查看遊戲範本的 main.dart 檔案,並向下捲動到第一個「TODO」,您將看到廣告、遊戲服務和應用程式內購 Plugin 的程式碼,處於休眠狀態,等待啟用。

Screenshot of disabled integration code from main.dart file: AdsController, GamesServices, and InAppPurchases.
停用的廣告、遊戲服務和應用程式內購程式碼

FCGT 中也包含了 Firebase Crashlytics,這是一個功能強大的錯誤報告解決方案,可幫助您實時偵測、追蹤、優先處理和修復問題。Crashlytics 儀表板讓您能夠將程式碼中的問題視覺化,查看受影響的使用者數量,並找出哪些程式碼行導致了這些問題。

Screenshot of Firebase Crashlytics dashboard showing Crash-free statistics, trends & issues.
Firebase Crashlytics 儀表板

在初始狀態下,未啟用 Crashlytics 時,crashlytics/crashlytics.dart 檔案中的程式碼會收集錯誤訊息、日誌和堆疊追蹤,並將它們寫入主控台。此資訊僅在本地開發設備上測試時可用。啟用 Crashlytics 後,您可以從在自己的設備上運行生產程式碼的使用者那裡接收資料,並在 Crashlytics 儀表板上查看它。

本文將向您展示如何在 FCGT 中啟用 Firebase Crashlytics,拋出一些測試異常,並演示這些異常如何在 Crashlytics 儀表板上顯示。如果您有興趣將 Crashlytics 用於您的 Flutter App,但不想使用 FCGT 開發遊戲,那麼有關拋出異常和 Crashlytics 儀表板的資訊適用於託管在 Firebase 上的任何應用程式。

main.dart 檔案 的頂部,您可以看到 Crashlytics 整合的程式碼:

Disabled Crashlytics code in main.dart file // To enable Firebase Crashlytics, uncomment the following lines and // the import statements at the top of this file. // See the ‘Crashlytics’ section of the main README.md file for details. FirebaseCrashlytics? crashlytics; // if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) { // try …
main.dart:停用的 Firebase Crashlytics 程式碼

此 Crashlytics Firebase 程式碼未包含在原始的 FCGT YouTube 影片教學中,使用 Flutter 建立遊戲的快速入門 - 這個程式碼很快就會說明。

在 FCGT 中啟用 Crashlytics 的步驟列在 FCGT 的 Crashlytics 區段README.md 檔案 中,但請繼續閱讀以了解每個步驟的逐步指南,以及 Crashlytics 儀表板中事物的外觀。

要開始,請使用以下說明:

  1. Flutter 專案 GitHub 頁面 下載最新版本的遊戲範本副本。

  2. 確保您已在電腦上安裝 Flutter,並且能夠在 iOS 模擬器或 Android 模擬器上運行應用程式。如果您對如何執行此操作有任何疑問,請參閱您的目標平台的 Flutter 入門指南

  3. 在您的 IDE 或終端機中打開遊戲範本資料夾,並升級到最新版本的 Flutter:

1
$ > flutter upgrade
  1. 選擇您要運行應用程式的設備或模擬器。

  2. 運行應用程式:

1
$ > flutter run

如果一切順利,應用程式將啟動,您將看到主畫面:

Screenshot of FCGT app main screen
遊戲範本主畫面

FCGT 的設計目的是讓開發人員能夠快速輕鬆地建立建立遊戲的基礎。在應用程式運行時,請在各個地方瀏覽並查看它可以做些什麼。您會很快發現 FCGT 中的「遊戲玩法」並不是最令人興奮的(除非您喜歡滑桿)。遊戲程式碼的淺層結構是一個刻意的設計選擇,讓您在開始撰寫自己的遊戲時保持簡單。

Animated gif of FCGT “game play”. User clicks “play” on main menu, selects “level #1", drags the slider to complete the level & the “You Won” screen is displayed.
FCGT「遊戲玩法」

現在您有了程式碼,請前往 Firebase 網站 並設定一個免費帳戶(如果您沒有帳戶)。然後,打開 Firebase 主控台 並點擊 新增專案。從那裡開始,建立一個新的專案是一個 3 步驟的過程,只要按照螢幕上的指示操作即可。系統會詢問您是否要啟用 Google Analytics (GA)。建議您啟用 Google Analytics,因為除了免費之外,它還解鎖了一些 功能強大的分析功能,例如無錯誤使用者資料、會話麵包屑、速度警報和 BigQuery 整合。

如果您啟用了 Google Analytics,請使用以下命令安裝 Google Analytics Flutter Plugin:

1
$ > flutter pub add firebase_analytics

若要進一步了解,請參閱 使用 Google Analytics 取得錯誤報告的指標 指南中的步驟 1 和 2,但無需遵循指南中概述的其他步驟,因為這些步驟已在下面說明。

接下來,安裝 Firebase CLI。前往 Firebase CLI 文件,選擇您的作業系統,並按照說明操作。登入後,在終端機中運行以下命令,它應該會顯示一個 Firebase 專案名稱列表:

1
$ > flutterfire configure

選擇您之前建立的 Firebase 專案的名稱。然後,選擇您的應用程式支援哪些目標平台。目前,Crashlytics 主控台僅支援 iOS 和 Android,因此最多選擇這兩個平台。

Result of typing “flutterfire configure” into the terminal. User is prompted to select a Firebase project, choose which platforms to support & then confirm Firebase configuration and gradle build plugins updates and FirebaseOptions file overwrite. Final result is the Firebase app IDs for the selected platforms.
FlutterFire 設定命令的輸出

FlutterFire CLI 會產生連接 Firebase 所需的所有金鑰和用戶端 ID,並將它們覆蓋到 src/firebase_options.dart 檔案中。如果您在未來添加更多 Plugin 或想要啟用更多平台,只需重新運行 flutterfire configure 命令即可。

要啟用 Crashlytics,請返回 lib/main.dart 檔案並取消註釋 Crashlytics 程式碼。在檔案的頂部,還有 3 個必須取消註釋的匯入語句:

3 import statements at the top of the main.dart file that need to be uncommented: dart:io, firebase_core.dart & firebase_options.dart.
取消註釋的 Crashlytics 匯入語句

然後,在同一檔案的下方,取消註釋您之前看過的 Crashlytics 整合程式碼。此程式碼會初始化一個 Crashlytics 的實例(如果還沒有實例),然後檢查應用程式是否正在 Android 或 iOS 上運行。如果應用程式正在桌面或網頁上運行,Crashlytics 程式碼將不會執行,因為 Crashlytics 儀表板還不支持這些平台。

Crashlytics code in main.dart file: FirebaseCrashlytics? crashlytics; if (!kIsWeb && (Platform.isIOS || Platform.isAndroid)) { try { WidgetsFlutterBinding.ensureInitialized(); await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); crashlytics = FirebaseCrashlytics.instance; } catch (e) { debugPrint(“Firebase couldn’t be initialized: $e”); } }
Crashlytics 整合程式碼

取消註釋 Crashlytics 整合程式碼後,請再次使用 flutter run 命令運行應用程式,以確保一切正常。

是時候讓您的應用程式當機了!

事實上,您只會拋出一些測試異常,但您也會了解如何在 Crashlytics 儀表板中找到它們。這很有用,因為未捕獲的異常可能不會導致您的應用程式當機,但仍然會導致糟糕的使用者體驗,而且如果沒有啟用 Crashlytics,它們可能會被忽略。crashlytics/crashlytics.dart 檔案中使用的 Crashlytics 致命錯誤 API 將未捕獲的異常報告為致命事件,因此它們將出現在 Crashlytics 儀表板中,並且可以適當優先處理。

Crashlytics Fatal Error API: FlutterError.onError = crashlytics.recordFlutterFatalError;
Crashlytics 致命錯誤 API

若要進一步了解如何實作此日誌記錄,請查看有關如何 自訂 Firebase Crashlytics 錯誤報告 的指南,並閱讀 crashlytics.dart 檔案中的註釋。

在您選擇的文字編輯器或 IDE 中,導航到 main_menu 資料夾,並打開 main_menu_screen.dart 檔案。向下捲動,直到找到 設定 按鈕的程式碼。

Code for settings button on main screen of app. ElevatedButton( onPressed: () => GoRouter.of(context).go(‘/settings’), child: const Text(‘Settings’), ),
之前(原始程式碼)

複製 ElevatedButton,然後在 onPressed 回呼中,不要呼叫 GoRouter 導航到 設定 頁面,而是拋出異常。在此過程中,請將按鈕的名稱更改為類似 拋出測試異常 的內容,如下所示:

1
2
3
4
5
6
7
8
9
ElevatedButton(
onPressed: () => GoRouter.of(context).go('/settings'),
child: const Text('Settings'),
),
_gap,
ElevatedButton(
onPressed: () => throw Exception(),
child: const Text("Throw Test Exception"),
),

接下來,導航到 audio 資料夾,並打開 audio_controller.dart 檔案。向下捲動,直到找到 _musicOnHandler 函數。當使用者在 設定 畫面中切換音樂播放時,框架會呼叫此函數。

Original code for _musicOnHandler() function from audio_controller.dart file.
之前(原始程式碼)

在 else 語句中,在呼叫 _stopMusic() 函數的地方下方,使用 _log.severe() 方法將訊息寫入主控台。任何等級為 Level.severe 或更高的日誌訊息都會發送給 Crashlytics,因此此訊息也會出現在 Crashlytics 主控台中。為了演示說明,請在此處也拋出另一個異常:

1
2
3
4
5
6
7
8
9
10
11
12
13
void _musicOnHandler() {
if (_settings!.musicOn.value) {
// Music got turned on.
if (!_settings!.muted.value) {
_resumeMusic();
}
} else {
// Music got turned off.
_stopMusic();
_log.severe("Someone is messing with the music!");
throw Exception();
}
}

現在,應用程式中有兩個地方可以點擊按鈕並拋出異常。再次運行您的應用程式,並確認在主選單中有一個 拋出測試異常 按鈕。

Screenshot of FCGT Main Menu with new “Throw Test Exception” button shown below the “Settings” button.
帶有拋出異常按鈕的主選單

點擊 拋出測試異常 按鈕會產生一個關於拋出異常時的完整堆疊追蹤,並將其寫入主控台:

Example console output after an exception is thrown with full stack trace. First 3 lines are: EXCEPTION CAUGHT BY GESTURE. The following _Exception was thrown while handling a gesture: Exception When the exception was thrown, this was the stack: …
拋出異常後的主控台輸出

如果點擊 設定 打開設定視圖,然後點擊樂符按鈕幾次,主控台中將會出現更多異常和堆疊追蹤。現在您啟用了 Crashlytics,此資料可以在 Crashlytics 儀表板中使用。

打開 Firebase 主控台,選擇您的專案,然後從左側的選單中選擇 Crashlytics。選擇您正在運行的專案版本(Android 或 iOS),您應該能夠看到 Crashlytics 儀表板。

Screenshot of Firebase Crashlytics dashboard showing Crash-free statistics, trends & issues.
Firebase Crashlytics 儀表板
如果幾分鐘後,當您嘗試存取 Crashlytics 儀表板時,只看到這個傢伙在錯誤中晃動,可能是因為 Crashlytics 還沒有偵測到任何事件。
在這種情況下,請停止應用程式運行,然後返回您的設備或模擬器,關閉應用程式,並透過點擊應用程式圖示再次啟動它。現在,嘗試在應用程式中拋出一些異常,並再次檢查 Crashlytics 儀表板。如果您刷新了 Firebase 主控台,手動重新啟動了應用程式,並且在五分鐘後仍然沒有看到測試錯誤,請 [啟用除錯日誌記錄](https://firebase.google.com/docs/crashlytics/test-implementation#enable-debug-logging) 以查看您的應用程式是否正在發送錯誤報告。
Cartoon image of man with butterfly net trying to catch bugs. This is displayed on the Crashlytics site when events haven’t been detected yet.
Crashlytics 尚未偵測到任何事件

如果您啟用了 Google Analytics,無錯誤統計資料窗格將會顯示在選定時間範圍內未遇到錯誤的使用者百分比。

Screenshot of the crash-free statistics pane from the Firebase Crashlytics dashboard
Crashlytics 儀表板無錯誤統計資料窗格

Crashlytics 儀表板底部 的 問題 表格顯示了拋出的異常。

Screenshot of the Issues table at the bottom of the Crashlytics dashboard. There are 2 example issues in the table. 1) Crash Fresh issue audio_controller.dart line 197 AudioController._musicOnHandler 2) Crash Fresh issue dart:async _BroadcastStreamController.add
Crashlytics 儀表板問題表格

點擊表格中的一個特定問題會顯示每當發生此問題時的卡片,以及有關該問題的更多詳細資訊。預設情況下,會顯示堆疊追蹤,這讓您能夠識別錯誤發生的程式碼位置。從下面的螢幕截圖中可以看出,異常是在 audio_controller.dart 檔案的第 197 行的 _musicOnHandler() 函數中拋出的。這並不奇怪,因為您正是將該異常放置在程式碼中的位置,但想像一下,這對於追蹤複雜的生產應用程式中的問題會有多有用。

Screenshot of an events summary in Crashlytics dashboard events table with a specific event selected and the stack trace tab selected.
Crashlytics 儀表板堆疊追蹤

如果您點擊 日誌 標籤,您可以看到 _log.severe() 方法寫入主控台的任何訊息:

Screenshot of an events summary in Crashlytics dashboard events table with a specific event selected and the log tab selected.
Crashlytics 儀表板日誌

恭喜您!現在,當您繼續撰寫獲獎遊戲(也許會有大量滑桿)時,您將啟用 Crashlytics 來幫助您找到和修復任何問題。


Firebase Crashlytics 和 Flutter 休閒遊戲工具包 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動翻譯產生】

編輯的快速輔助

您是否在編碼時花費太多時間執行重複性的任務?如果是這樣,那麼我有一些好消息要告訴您。許多重複性的任務可以使用我們稱為「快速輔助」的功能自動執行。

快速輔助 是一種自動編輯,旨在對程式碼進行常見的更改。與我們在針對分析問題的快速修復批量應用修復中看到的快速修復不同,快速輔助的存在並不是建議您更改程式碼,它只是為了讓您的工作更輕鬆。

讓我們來看幾個例子。

宣告局部變數

您可能會花費相當多的時間宣告和初始化局部變數。這些工具可以幫助您完成其中的一些工作。如果您輸入初始化運算式,則可以使用快速輔助來建立局部變數以擷取運算式的值。

如果您從下面的程式碼開始,並將游標放在運算式中的任何位置,則燈泡圖示會出現在編輯器左側邊緣附近。如果您將滑鼠懸停在它上面,則可以點擊以打開包含可用快速輔助的選單。

Visual Studio Code
IntelliJ IDEA

選擇輔助會插入變數宣告,使用運算式作為初始化運算式,並選取變數的名稱,以便您可以選擇建議的名稱之一或輸入您自己的名稱:

Visual Studio Code
IntelliJ IDEA

按下 Enter/Return 鍵即可接受輸入的名稱。

函式主體樣式

如果您經常使用運算式主體函式,則您可能需要在某些時候將其轉換為程式碼塊主體函式。也有一個輔助可以做到這一點。例如,如果您有如下程式碼,並且您將游標放在箭頭內,您將看到以下選項:

Visual Studio Code
IntelliJ IDEA

選擇「轉換為程式碼塊主體」會將函式主體改寫為如下所示:

Visual Studio Code
IntelliJ IDEA

是的,還有另一個輔助可以將程式碼塊主體轉換為運算式主體。

改寫 if 陳述式

輔助還可以幫助進行更大的重構。如果您曾經編寫過如下結構的程式碼:

1
2
3
4
5
6
7
void f(int a, int b, int c, int d) {
if (a == b) {
if (a == c || a == d) {
print(0);
}
}
}

並且意識到您可以組合這兩個條件,則有一個輔助可以做到這一點。將游標放在內部的 if 上並打開選單:

Visual Studio Code
IntelliJ IDEA

選擇「將 ‘if’ 陳述式與外部 ‘if’ 陳述式合併」會將程式碼改寫為如下所示:

1
2
3
4
5
void f(int a, int b, int c, int d) {
if (a == b && (a == c || a == d)) {
print(0);
}
}

如果您將游標放在外部的 if 上,輔助也會顯示,但選單會顯示「將 ‘if’ 陳述式與內部 ‘if’ 陳述式合併」。

使用新的語言功能

還有一些輔助可以幫助您轉換到新的語言功能。例如,如果您有一個如下所示的類別:

1
2
3
4
5
6
7
class A {
A({int? x, int? y});
}

class B extends A {
B({int? x, int? y}) : super(x: x, y: y);
}

其中子類別中的建構函式將一些參數傳遞給父類別而不修改它們,則有一種更簡潔的程式碼編寫方式。將游標放在建構函式 B 的名稱上並打開選單:

Visual Studio Code
IntelliJ IDEA

選擇「轉換為使用父類別參數」會將程式碼改寫為如下所示:

Visual Studio Code
IntelliJ IDEA

可用的輔助比我們在一篇文章中所能涵蓋的要多。下次您發現自己要執行經常執行的編輯時,請查看上下文操作,看看是否有輔助可以讓任務更輕鬆。


用於編輯的快速輔助 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

只需幾行程式碼,就能將 Flutter 功能連接到原生應用程式,並迅速啟動!

如果您一直想要嘗試使用 Flutter,但又不想從頭開始構建,那麼 Flutter 的 新增至應用程式功能 就是一個很棒的起點。為了讓您更輕鬆地將 Flutter 投入使用,我們與 Flutter 團隊合作,創建了一個新增至應用程式的示例原型,以展示如何在付出最少努力的情況下,將 Flutter 整合到原生程式碼庫中。無論您是想試用 Flutter,還是想以實際的方式向您的團隊展示 Flutter 的運作方式,這篇文章都適合您!

將 Flutter 新增到原生新聞提要應用程式

在本教程中,我們將向您展示如何使用 Flutter 的新增至應用程式 API,僅需幾行程式碼,就能將 Flutter 功能整合到原生應用程式中。

我們將要查看的專案分為兩個部分。第一部分包含三個針對三個獨立原生平台(Android、iOS 和 Web)的相同新聞提要應用程式。該應用程式是互動式的,因此您可以在設備上運行它,捲動文章,點擊新聞項目等等。此專案的第二部分是一個對話方塊,當您與應用程式互動時會彈出,並要求使用者提交反饋。此功能我們將稱之為 NPS(淨推薦值)模組,它是使用 Flutter 構建的。

首先,前往 示例儲存庫。您將看到每個平台的資料夾,其中包含新聞提要應用程式的原生程式碼。儲存庫中還有一個 flutter_nps 資料夾,其中包含 NPS 模組的所有 Flutter 程式碼。

使用 Angular 將 Flutter 新增到 Web

Flutter 模組在原生 Web 應用程式中作為一個 <iframe> 執行。要將此功能整合到 Angular 程式碼庫中,首先運行針對 Web 目標的 Flutter 構建。此步驟將生成一個 index.html 以及其他必要的檔案。將所有構建檔案複製到 Angular 應用程式 src 資料夾中。從那裡,您可以在 iframe 中引用構建檔案。下次運行 Web 應用程式時,您將看到 Flutter 功能!

查看 README 以獲取完整說明

使用 Kotlin 將 Flutter 新增到 Android

現在讓我們將 NPS 模組加入到 Android 應用程式中。首先使用快取的引擎開始一個 Flutter 活動。當您啟動原生新聞應用程式時,Flutter 引擎會在背景中預熱。然後,您將開始一個新的活動,並將其指向 Flutter 活動。這確保了從原生 Kotlin 程式碼到 Flutter 的快速轉換,並允許 Flutter 功能在 Android 應用程式中無縫運作。

查看 README 以獲取完整說明

使用 SwiftUI 將 Flutter 新增到 iOS

最後,我們可以將 NPS 模組加入到 iOS 應用程式中。首先,將編譯後的 Flutter 模組嵌入到 Xcode 的構建設定中。然後,在您的應用程式委託中,創建一個 Flutter 引擎的實例並啟動它。完成之後,您就可以在需要的地方顯示 Flutter UI - 只需使用 Flutter 引擎創建一個 FlutterViewController 並呈現它。然後使用路徑運行 flutter build ios-framework

查看 README 以獲取完整說明

將 Flutter 投入您的使用(以及您的團隊!)

現在您已在應用程式中運行 Flutter 程式碼,您可以試驗 Flutter 的一些有趣部分。以下幾個部分包含一些開始的地方。

支援多個平台

在此新聞提要示例中,您可以看到 NPS 模組是如何支援平台差異的。在 Web 上,此模組顯示為新聞提要頂部的對話方塊,並對來自滑鼠或螢幕閱讀器的輸入做出反應。在行動設備上,此模組佔用整個螢幕空間,並透過觸控或螢幕閱讀器接受輸入。

請注意,Flutter NPS 模組包含 Material Widget,它會根據使用者的設備自動處理手勢偵測。如果您使用的是桌面設備,那麼應用程式會接收滑鼠輸入,如果您使用的是行動設備,那麼應用程式會接收觸控輸入。

動畫

此原型包含一些 隱式動畫,由於它們是內建在 Flutter 框架中的,因此很容易調整。例如,如果您想對 AnimatedContainer Widget 進行更改,只需調整其屬性,例如動畫持續時間、容器高度、形狀和顏色。

1
2
3
4
5
6
7
8
9
10
11
12
...
return AnimatedContainer(
duration: duration,
height: Spacing.huge,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isSelected
? NpsColors.colorSecondary
: NpsColors.colorGrey5,
),
...
);

NPS 模組包含一個自訂頁面動畫轉場。查看 SlideTransition Widget 以獲取另一個動畫示例,可以透過更新其持續時間和其他元素來自訂。

1
2
3
4
5
6
7
SlideTransition(
position: Tween<Offset>(
begin: const Offset(0, 1),
end: Offset.zero,
).animate(animation),
child: child,
);

如果您想將動畫提升到另一個層級,您可以從 pub.dev 中導入 animations 套件,並使用一些花哨的預建動畫。

主題

更新 NPS 模組的主題也很簡單。由於它透過 ThemeData 使用內建的 Material 主題,因此您只需在一个位置更新顏色、按鈕樣式和字體即可。例如,要使用 Flutter 更改 NPS 模組的 accentColor 和 backgroundColor,請使用提供的 Material 顏色配置 或您想要的自訂顏色,更新為您想要的顏色。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class AppTheme {
ThemeData get theme => ThemeData(
colorScheme: ColorScheme.fromSwatch(
accentColor: NpsColors.colorSecondary,
backgroundColor: NpsColors.colorWhite,
),
scaffoldBackgroundColor: NpsColors.colorWhite,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
primary: NpsColors.colorSecondary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(24),
),
).copyWith(
backgroundColor: MaterialStateProperty.resolveWith<Color?>(
(Set<MaterialState> states) {
if (!states.contains(MaterialState.disabled)) {
return NpsColors.colorSecondary;
} else if (states.contains(MaterialState.disabled)) {
return NpsColors.colorWhite;
}
return null;
},
),
),
),
textTheme: const TextTheme(
headline5: NpsStyles.headline5,
subtitle1: NpsStyles.subtitle1,
bodyText2: NpsStyles.link,
),
);

其他功能

Flutter NPS 模組使用 flutter_bloc 進行狀態管理,以跟踪使用者的分數回覆。Cubit 是構建 Flutter 應用程式時 許多狀態管理選項 之一。此功能還包含 單元測試和 Widget 測試,它們是有用的工具,可以確保您正在編寫的程式碼按預期工作。最後,程式碼庫具有 78 種語言的本地化支援。此專案具有 用於持續整合的 GitHub Actions 整合,可以在合併更改之前運行格式化、棉絨檢查和測試階段。

後端

雖然此原型目前不與後端互動,但您可以使用您選擇的後端配置它,以便儲存來自 NPS 模組的資料,或者甚至為原生新聞提要引入示例文章。可以探索的一個選項是 Firebase,它與 Flutter 無縫整合在一起。查看 Firebase 文件,將 Firebase 添加到您的 Flutter 應用程式中

現在您知道如何將 Flutter 功能加入到原生 Web、Android 和 iOS 程式碼庫中,您就可以按照類似的流程將此功能整合到任何原生應用程式中。查看完整的 新增至應用程式文件,以獲取更多資訊。

此處的開源儲存庫 中查看完整的程式碼。


讓 Flutter 為您所用 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

宣布 Flutter 休閒遊戲工具包

對大多數開發人員來說,Flutter 是一個應用程式框架。但圍繞著休閒遊戲開發也有一個不斷發展的社群,他們利用 Flutter 提供的硬體加速圖形支援。

在過去的一年中,成千上萬的 Flutter 遊戲已發佈。例如,Lotum,開發史上最受歡迎的文字拼圖遊戲 [4 Pics 1 Word](https://flutter.dev/showcase/lotum) 的遊戲公司,用 Flutter 重寫了整個遊戲。[Flame](https://flame-engine.org/),一個建立在 Flutter 之上的社群驅動的開源遊戲引擎,其貢獻者和使用者一直在穩定地增長。

在 Flutter 中開發的手機遊戲

為了了解我們如何提供更好的支援,我們 [採訪了幾位開發人員](https://medium.com/flutter/perspectives-from-early-adopters-of-flutter-as-a-game-development-tool-f95fb3406d51),他們已成功構建並發佈了 Flutter 手機遊戲。我們詢問他們使用 Flutter 建立遊戲的感受,他們的回答揭示了幾個主題:

  • Flutter 簡單易學,易於用於構建 UI 和休閒遊戲
  • Flutter 允許他們查看框架原始碼(沒有「黑盒子」)並完全控制畫布
  • Flutter 擁有一個開放的生態系統,您可以在其中找到(並利用)許多有用的套件、外掛和函式庫
  • Flutter 可移植 - 您只需編寫一次程式碼,遊戲就會預設編譯為多平台

同時,研究參與者提到,建立 Flutter 遊戲的最大挑戰是找到資源和學習材料,以便開始使用並整合到平台遊戲服務中。為了滿足這些需求,我們正在發佈一個新的入門工具包,以加速您的遊戲開發。

全新的 [Flutter 休閒遊戲工具包](http://flutter.dev/games) 提供了一個專用的範本(由 [Filip Hracek](https://github.com/filiph) 開發),您可以使用它來構建自己的遊戲。這個入門專案提供了預先構建的「鈴鐺和哨子」,例如主選單、設定頁面、聲音支援等等,但有趣的部份留給您:構建遊戲!

在手機上運行的井字遊戲

影片教學

若要開始使用,請查看有關如何使用遊戲範本的 [影片教學](https://youtu.be/zGgeBNiRy-8)。它提供了有關構建 [井字遊戲](https://github.com/filiph/tictactoe) 的逐步指南(也可以從 [iOS](https://apps.apple.com/us/app/tic-tac-toe-puzzle-game/id1611729977) / [Android](https://play.google.com/store/apps/details?id=dev.flutter.tictactoe) 商店下載)。若要查看 Filip 在開發遊戲時遇到的所有細節,請查看他的 [原始開發日誌](https://docs.google.com/document/d/e/2PACX-1vRM-pZYVNOcJhCh5-ZHt8jGwWpNvx4KtpJZECHmaUPn9PIOgdTThK5OBRblCM6PQC4skqDRdW0lJnyM/pub)。

預先整合的服務

除了遊戲可能需要的常見 UI 和功能元素外,您還獲得了遊戲開發所需的關鍵服務的預先整合模組和範例程式碼。例如,遊戲範本整合了 Apple Game Center 和 Google Play Games Services,以便您可以輕鬆地顯示排行榜和成就等功能。

如果您打算讓您的遊戲盈利,範本使用 [Google 行動廣告 SDK](https://pub.dev/packages/google_mobile_ads),並向您展示如何實作範例廣告。範本還使用 [應用程式內購買](https://pub.dev/packages/in_app_purchase) 套件,讓您可以在遊戲中為玩家提供額外的內容,例如高級體驗、數位商品和訂閱。

最後,遊戲範本包含 [Firebase Crashlytics](https://pub.dev/packages/firebase_crashlytics),因此您可以深入了解遊戲中可能發生的任何崩潰或錯誤。所有遊戲範本的原始碼都可以在 GitHub 上的這個 [Flutter 範例儲存庫](https://github.com/flutter/samples/tree/master/game_template#readme) 中找到。

Flutter 遊戲 Discord 頻道

Flutter 的優勢之一是其樂於助人且熱情的社群。若要與其他 Flutter 遊戲開發人員聊天、提出問題和分享最佳實務,請考慮加入 r/FlutterDev Discord 伺服器上的 [專用遊戲頻道](https://discord.gg/WY5NwwjBQz)!非常感謝 Flutter 社群成員 @Miyoyo 幫助建立這個社群空間來支援 Flutter 遊戲開發人員!(順便說一下,如果您已經是 r/FlutterDev 社群的成員,以下是一個 [直接連結](https://discord.com/channels/420324994703163402/964110538986651658)。)

如果您的遊戲需要 Cloud 或 Firebase 服務,或者您想透過廣告將您的遊戲推廣給更多使用者,您可以獲得 [Google Ads](https://ads.google.com/intl/en_us/home/flutter/#!/) 和 [Cloud](https://cloud.google.com/free?utm_source=flutter&utm_medium=display&utm_campaign=FY22-Q2-flutter-games_get-started&utm_content=-&utm_term=-) 團隊提供的最高 900 美元的信用額度(適用條款和限制)!

從手機開始,但超越它

我們從過去的研究中了解到,如今大多數 Flutter 遊戲都是休閒手機遊戲,因此我们在設計 Flutter 休閒遊戲工具包時優先考慮了手機場景。

這並不意味著您的創造力應該局限於手機平台。事實上,範例 [井字遊戲](https://github.com/filiph/tictactoe) 可以在 [網頁](https://filiph.github.io/tictactoe/) 和桌面上運行!

在網頁和桌面上運行的井字遊戲

同時,我們最近在 DartPad 上加入了對社群驅動的遊戲引擎 Flame 的支援,因此您可以在 DartPad 上探索 [使用 Flame 構建遊戲](https://dartpad.dev/?id=3e52ca7b51ba15f989ad880b8b3314a2),而無需下載 SDK。更重要的是,由 Very Good Ventures (VGV) 撰寫並在 Google I/O 上推出的基於網頁的 [彈珠遊戲](https://pinball.flutter.dev/),是用 Flutter 使用 Flame 引擎構建的!若要了解彈珠遊戲是如何建立的,請查看 VGV 團隊的 [彈珠文章](https://medium.com/flutter/i-o-pinball-powered-by-flutter-and-firebase-d22423f3f5d) 或 [查看程式碼](https://github.com/flutter/pinball)。

基於網頁的彈珠遊戲

遊戲開發是 Flutter 正在發展的一個令人興奮的新場景!展望未來,我們希望加入更多 codelab 和其他資源,幫助您開發遊戲。這是我們第一次嘗試讓您更容易使用,我們充分意識到可能存在許多改進的空間。我們最近開始與社群成員 [wolfenrain](https://github.com/wolfenrain) 合作,對遊戲相關的議題進行分類。如果您需要希望 Flutter SDK 能更好地支援的產品功能,請在 GitHub 上提交議題(或為現有的議題投票)。

flutter.dev/games

請查看專用的 [遊戲開發](http://flutter.dev/games) 頁面,您可以在此了解上面提到的資源,還可以找到指向 [文件](http://docs.flutter.dev/resources/games-toolkit) 的連結,以及 Flutter 社群遊戲開發專家推薦的函式庫、套件和工具的參考。

自 Flutter 1.0 發佈以來,您不斷以出色的應用程式讓我們驚嘆不已,現在我們迫不及待地想看看您將使用 Flutter 推出什麼令人興奮的遊戲!


宣布 Flutter 休閒遊戲工具包 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

來自 Flutter 遊戲開發工具早期採用者的觀點

簡介

在今年的 Google I/O 上,我們推出了 Flutter 休閒遊戲工具包,這個工具包是一套資源,用於支援 Flutter 社群中的遊戲開發者。在此之前,Flutter 並未將遊戲開發作為官方支援的用例,儘管我們對一些成功案例印象深刻,例如流行的文字解謎遊戲 4 圖 1 字 以及 Flame 引擎等社群努力。那麼,為什麼我們決定正式支持遊戲開發,以及我們如何決定工具包的初始版本應該包含哪些內容呢? 在這篇文章中,我們將分享與 Flutter 遊戲開發工具的早期採用者進行的兩項使用者研究,並解釋他們的觀點如何塑造我們的策略和工具包的設計。

我們從一項訪談研究開始,在研究中,我們分別與 6 位成功開發和發佈了 Flutter 遊戲的開發者(稱為 P01 到 P06)進行了會面。我們對這項研究有兩個目標。第一是了解哪些類型的資源對於開始進行 Flutter 遊戲開發最有用。第二是更好地了解 Flutter 開發者在遊戲開發中的動機、需求和痛點,並利用這種理解來戰略性地規劃我們對該領域的長期投資。為了補充訪談的定性研究結果,我們還在廣泛的 Flutter 使用者社群中針對這個主題進行了一項調查。

在本文的其餘部分,我們首先總結了訪談和調查研究的主要發現,然後我們分享關於市場定位、文件和學習資源以及潛在的長期投資以支援 Flutter 遊戲開發者的建議。

開發者訪談的發現

Flutter 遊戲開發者的背景

總體而言,我們發現了當今存在的兩種 Flutter 遊戲開發者原型:

  • 應用程式 - 遊戲混合開發者: 他們是 Flutter 應用程式開發者,但他們也利用 Flutter 開發相對簡單的遊戲,而不需要使用其他工具。(P02、P04 和 P05)
  • 計算機藝術家和圖形愛好者: 他們主要被 Flutter 提供的對圖形的控制程度所吸引,但他們可能不會將 Flutter 用於應用程式開發。(P01 和 P03)

下表提供了有關我們在本次研究中所訪談的開發者背景的更多資訊。有幾位是由 Flame 團隊推薦給我們的。

使用 Flutter 開發遊戲的感知益處

參與者列出了使用 Flutter 開發遊戲的許多益處。我們列出了下面由多位參與者提到的那些益處:

  • 簡單性: 參與者認為,與 Unity 和 Unreal 等大型遊戲引擎相比,使用 Flutter 開發 2D 休閒遊戲更容易上手,也更不複雜。(P03、P04)
  • 控制: 參與者欣賞能夠在 IDE 中看到 Flutter 的原始碼,並完全直接地控制畫布。(P01、P02、P04)
  • 生態系統: 開發者可以利用 Flutter 生態系統中的套件,例如資料持久性和音訊播放。(P01、P02、P03、P04)具體而言,P01 認為 Flutter 的音訊功能優於其他跨平台 UI 工具包。
  • 跨平台: 參與者欣賞輕鬆部署到 iOS 和 Android 的便利性,並認為它提供了「真正的單一程式碼庫」。 (P01) 但是,由於遊戲引擎通常是跨平台的,所以這並不常被提及。
  • 輕鬆建立 UI: Flutter 遊戲可以在其 UI 中輕鬆利用任何 Flutter Widget。(P04、P05)這對於更類似於應用程式的遊戲特別有用,這些遊戲不需要使用遊戲引擎(例如,P05 和 P06 開發的文字解謎遊戲)。
  • 學習機會: Flutter 和 Flame 的開源性質提供了一個機會,透過開發遊戲來深入了解遊戲引擎和圖形管線。(P03)
  • Flame 遊戲引擎: 使用 Flame 的參與者普遍對該專案及其功能以及 Flame 提供的支持表示肯定。P04 特別是在 Flutter 上開發了一款遊戲,因為他發現了 Flame。

使用 Flutter 開發遊戲的感知挑戰

作為一個新興用例,在 Flutter 上開發遊戲並非沒有挑戰。參與者強調了他們在各自專案中遇到的以下問題:

  • 整合和生態系統:

    • 难以與 Play 遊戲服務整合。(P01、P03)
    • 缺少用於離線優先資料庫的良好選項,這些資料庫具有衝突管理功能。(P05)
    • 需要指導以選擇最佳的音訊外掛,該外掛可以同時在前景和背景中播放音訊。(P05)
    • 資產:尋找和建立高品質的遊戲資產非常耗時。(P02、P03、P04)
    • 這可能是最耗時的過程。如果我找不到彼此相符的資產,遊戲看起來就不會完全是我想要的樣子。而且由於我不太擅長製作藝術品,所以找到合適的資產對我來說是最具挑戰性的任務。 (P03) *
  • Flame 特定的挑戰:

    • 參與者指出,Flame 的文件對初學者不友好。特別是,Forge2D(Flame 的一部分)需要更好的文件。(P03、P04)
    • 參與者指出,Flame 中的碰撞檢測過於基礎。在兩個物體碰撞後,它不會處理物理效果,除非您使用 Forge2D。(P03)
  • Flutter SDK 和工具中缺少的功能:

    • 缺乏 3D 支援。(P02、P03)但是,這對這些參與者來說似乎並不重要。
    • 沒有用於濾鏡、效果、層或合成圖的直接著色器訪問權。(P01、P02)這對熱衷於電腦圖形的參與者來說比較重要。
    • 缺少用於控制更新率(例如 120hz)的使用者空間 API。(P01、P02)
    • 不確定 Flutter 是否擁有提供對畫面緩衝區可見性的著色器除錯工具。Xcode 有很棒的 OpenGL 除錯工具。(P01)
  • 效能和套件大小:

    • DevTools 在診斷具有遊戲迴圈的遊戲的效能問題時並不總是很有用。(P02)
    • 在低階 iOS 設備上存在動畫卡頓。著色器預熱解決方案很有用,但非常耗費人力。 (P05) 也沒有關於如何做到的視訊教學。(P03)
    • 缺乏對根據設備的效能特性調整應用程式渲染品質的支持。 (P05)
    • Web 套件大小對於 Facebook Instant Game 等網頁遊戲平台來說太大。 (P05)

將 Flutter 與其他遊戲開發工具進行比較

由於本研究的選擇標準,所有參與者對其他遊戲引擎的經驗都非常有限。但是,他們就入門、控制感和套件生態系統提供了他們的印象。

首先,參與者認為 Flutter/Flame 比 Unity 和 Unreal 等大型遊戲引擎更容易上手和理解。(P01、P02、P03、P04)參與者發現,Unity 或 Unreal 中的許多功能與他們正在開發的遊戲類型無關。

其次,由於我們的參與者是經驗豐富的程式設計師,他們發現很難從 Unity 或 Unreal 的低程式碼開發環境中獲得他們需要的控制權。

我真的很喜歡深入研究並完全控制所有細節。因此,使用 Flutter,Flame 引擎非常開放。我覺得我真的擁有完全的控制權,而在 Unity 中,一切都隱藏起來了。他們試圖為休閒使用者自動化某些操作。 (P01)

最後但並非最不重要的是,Flutter 的生態系統被認為優於其他輕量級遊戲引擎,例如 Godot(P02、P03)。例如,P03 表示,使用 package:hive,在原生平台上進行資料持久化非常容易。他懷疑使用 Godot 可能需要原生程式碼。

對第一次使用 Flutter 開發遊戲的開發者有用的資源

所有參與者都提到,在開始使用 Flutter 開發遊戲時,他們需要更好的文件和學習資源。為了確定優先順序,我們要求參與者透過將不同類型的資源分類到三個桶中來評估它們對遊戲開發的重要性:必須擁有應該擁有可以擁有。以下清單顯示了所得的桶:

「必須擁有」的資源包括:

  • 一個 範例遊戲,其中預先整合了常見的遊戲特定技術(例如音訊支援)和平台遊戲服務(例如 Google Play 服務)。

  • 一個專用的網站,其中包含所有遊戲開發資源以及有關第三方服務(例如套件、資產市場)的推薦。

  • 操作指南視訊,涵蓋基本的遊戲開發概念(例如遊戲迴圈)、與後端的整合、遊戲支援和變現服務。P03 也對像 無聊的表演 等長篇視訊感興趣,這些視訊涵蓋了整個遊戲開發過程,包括疑難排解:

    • 我覺得兩種不同的 [視訊] 內容會更好。一種是類似於「本週 Widget」的非常短的內容,然後是類似於「無聊的 Flutter 表演」的內容,其中您會深入了解整個過程,並逐步完成建立該遊戲的所有步驟。 (P03)*

「應該擁有」的資源包括:

  • 一個專門針對 Flutter 遊戲的 Discord 頻道,這個頻道比 Flame 團隊的 Discord 更通用。

「可以擁有」的資源包括:

  • Codelabs
  • 教師指導的研討會
  • Google 服務的信用額度(例如 GCP、廣告、Firebase)
  • 直接存取專用支援

根據參與者的寶貴意見,我們在休閒遊戲工具包的初始版本中優先考慮了「必須擁有」的資源。

調查的發現

如前所述,我們進行了一項補充調查,以更廣泛地了解 Flutter 社群中的遊戲開發情況。以下圖表顯示了高階結果:

Flutter 使用者有興趣使用 Flutter 開發遊戲

許多 Flutter 使用者(62.4%)不知道他們可以使用 Flutter 開發遊戲,這並不奇怪。然而,39.2% 的人有興趣了解更多。

Results for the survey question “Did you know that you can use Flutter to build games?” 39.3% — “No, and I’m interested in learning more.” 37.6% — “Yes.” 23.2% — “No, I’m not interested in the topic.”

許多 Flutter 使用者對使用 Flutter 開發遊戲的廣泛興趣也反映在許多 Flutter 使用者對遊戲開發並不陌生這一事實中。在 936 位受訪者中,有 500 多人有使用 Unity 的經驗,130 多人有使用 Unreal 的經驗,120 多人有使用 Flame 的經驗,80 多人有使用 Godot 的經驗。看到這麼多開發者已經具備遊戲開發技能,這令人鼓舞。

許多 Flutter 遊戲開發者才剛起步

然後,我們詢問那些了解或對 Flutter 開發遊戲的能力感興趣的人,他們在遊戲開發過程中處於什麼階段。在這個群體中,43.2% 尚未開始具體的遊戲專案,這表明需要入門支持。

Summarized responses to the question: “which of the following statements best describe your experience using Flutter to build games?”

比我們想像的更多 Flutter 遊戲已經出現

我們要求受訪者向我們指出他們使用 Flutter 開發的任何遊戲。令我們驚訝的是,我們收到了 148 個回覆。其中許多遊戲是 2D 解謎遊戲或 平台遊戲,而其中一小部分嘗試使用 Flutter 創造擬 3D 效果。

使用 Flutter 開發非常成功的行動遊戲似乎是完全可能的。例如,我們透過這項調查了解的 Flutter 遊戲 Kelimelik 在撰寫本文時在 Google Play 上獲得了 4.5 星的評分,有 356,000 多條評論和 500 萬次安裝!

The kelimelik game’s listing on the Google Play store.

Flutter 使用者希望更多關於遊戲開發的文件

當我們詢問受訪者什麼因素阻礙了他們在遊戲專案中的進展時,我們收到了 31 個回覆。其中許多與缺乏文件有關:

  • 「沒有足夠的教學,我沒有理解透徹。」
  • 「沒有足夠的資源/教學/文件 (flutter flame)。」
  • 「文件對初學者遊戲開發者並不友好。在教學或案例研究演練中,還有很多工作要做,才能為 Flame 元件建立一個非常清晰的入門介紹,並提供常見的場景,以幫助新入門者。」

這個回饋呼應了我們從訪談研究中了解到的內容。調查受訪者還提到了缺少 3D 支援、使用著色器遇到困難以及特定硬體和視覺效果(例如陰影)的效能問題。

建議

我們的研究結果顯示了在 Flutter 上開發 2D 休閒遊戲的潛力。一些 Flutter 使用者嘗試過並成功發佈了高評分的遊戲,還有更多使用者有興趣在未來的幾個月裡開始嘗試。

為了讓這些新的遊戲開發者取得成功,我們必須適當地定位 Flutter 在市場上其他遊戲開發工具中的位置,並利用 Flutter 開放和參與的性質來完善其對遊戲開發的支持。

基於此,我們想提出一些建議,這些建議不僅針對 Google 的 Flutter 團隊,也針對 Flutter 社群的套件作者、工具開發者和內容創作者。

市場定位

研究結果表明了我們在遊戲開發工具市場中定位 Flutter 時需要考慮的三个维度:

遊戲類型:

  • 以 2D 休閒遊戲為目標是一個良好的起點。
  • 解謎遊戲和平台遊戲是在 Flutter 中開發的成功子類別。

開發者類型:

  • 希望利用 Flutter 的休閒遊戲開發能力的 Flutter 應用程式開發者(例如 P02、P04 和 P05)。
  • 被 Flutter 提供的高度控制和開放性所吸引的計算機藝術家和圖形愛好者(例如 P01 和 P03)。

遊戲開發團隊類型:

  • 我們可以專注於獨立遊戲開發者和混合遊戲/應用程式代理商,這些代理商的專業角色較少,可以從 Flutter 的跨平台功能中獲益更多。

文件和學習資源

根據訪談研究的使用者意見,我們認為 Flutter 社群中的創作者和教育工作者可以透過專注於建立開源範例遊戲、操作指南視訊和為遊戲開發策劃資源列表來發揮最大作用。我們在 I/O 上發佈的 Flutter 休閒遊戲工具包是我們沿著這些方向組織資源並提高它們在 Flutter 使用者中的可見度的第一次嘗試。

對 Flutter API 和功能的潛在投資

在研究過程中,參與者指出了他們希望 Flutter SDK 在未來更好地支援的一些主要產品功能:

  • 著色器的可用性和支援(GitHub 議題)。或者,如果函式庫維護者(例如 Flame)直接使用著色器 API,可能就足夠了(例如,P03 希望遊戲引擎中有一個更高階的抽象)。
  • Web 應用程式套件大小。一位參與者指出了將遊戲擴展到基於網頁的遊戲平台(例如 Facebook Instant Game)的問題。由於 Web 套件大小過大,他們最終選擇了 HTML 渲染後端,而不是速度更快但更大的 Canvas Kit 後端。(P05)
  • Windows/Steam 支援。多位參與者表達了對嘗試使用他們的遊戲的全新 Windows 支援的濃厚興趣。其中一人提到,Windows 是最需要支持的平台,特別是如果您打算在 Steam 上發佈您的遊戲。(P03)但是,鑑於沒有參與者或我們的團隊成員在 Windows 上測試過遊戲開發或整合 Steam,所以這種情況仍然不明確。

除了這三個改進領域之外,我們最近開始與社群成員合作,對與遊戲相關的議題進行分類,並將它們標記為 a: gamedev

結論

我們從這兩項研究中了解到,包括 Flutter 使用者對遊戲開發的廣泛興趣,以及現有 Flutter 遊戲開發者所欣賞的 Flutter 的簡單性和高度控制,讓團隊對追求遊戲開發作為可行的用例充滿信心。休閒遊戲工具包是我們在這個領域的第一項投資,我們期待在後續研究中了解我們的社群成員如何利用它。

致謝

Zoey FanChristopher FujinoJaYoung Lee 參與了這項研究,Shams Zakhour 編輯了這篇文章。我們要感謝參與這項研究的使用者,以及 Flame 團隊在參與者招募方面的支持。


來自 Flutter 遊戲開發工具早期採用者的觀點 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章內容使用 Gemini 1.5 Pro 自動產生】

邁向多平台 UI 開發的旅程:手機、桌面和網頁

我們很興奮地宣布,作為 Google I/O 主題演講的一部分,Flutter 3 正式推出。Flutter 3 完成了我們從以行動為中心的框架到多平台框架的路線圖,其中包含 macOS 和 Linux 桌面應用程式支援的可用性,以及 Firebase 整合的改進、新的生產力與效能功能,以及對 Apple Silicon 的支援。

Flutter 3 的旅程

我們最初開發 Flutter 的目標是徹底改變應用程式開發:將網頁的迭代開發模式與硬體加速的圖形渲染和像素級別控制(以前是遊戲的專利)結合起來。在 Flutter 1.0 beta 發佈後的過去四年裡,我們在這些基礎之上不斷發展,新增了新的框架功能和 Widget、與底層平台更深層次的整合、豐富的套件函式庫,以及許多效能和工具方面的改進。

隨著產品的成熟,越來越多的人開始使用 Flutter 構建應用程式。如今,使用 Flutter 構建的應用程式超過 500,000 個。來自 data.ai 等研究機構的分析,以及公開的見證表明,Flutter 被許多領域的 廣泛客戶群 使用:從像 微信 這樣的社交應用程式,到像 BettermentNubank 這樣的金融和銀行應用程式;從像 SHEINtrip.com 這樣的電商應用程式,到像 FasticTabcorp 這樣的休閒應用程式;從像 My BMW 這樣的伴侶應用程式,到像 巴西政府 這樣的公共機構。

如今,使用 Flutter 構建的應用程式超過 500,000 個。

開發人員告訴我們,Flutter 有助於更快速地為更多平台構建更精美的應用程式。在我們最近的使用者研究中:

  • 91% 的開發人員同意 Flutter 縮短了構建和發佈應用程式所需的時間。
  • 85% 的開發人員同意 Flutter 使他們的應用程式比以前更精美。
  • 85% 的開發人員同意它使他們能夠為比以前更多的平台發佈應用程式。

Sonos 最近的一篇部落格文章 中,他們討論了他們改進的設定體驗,並強調了其中第二點:

「毫不誇張地說,[Flutter] 解鎖了我們團隊以前從未實現的「*高級*」程度。對我們的設計師來說,最重要的是,可以輕鬆構建新的 UI,意味著我們的團隊花在對規格說「不」上的時間更少,花在迭代上的時間更多。如果這聽起來很划算,我們建議您試試 Flutter - 我們很慶幸我們嘗試了。」

介紹 Flutter 3

今天,我們推出 Flutter 3,這是我們完成 Flutter 支援平台的旅程的成果。使用 Flutter 3,您可以從單個程式碼庫中為六個平台構建精美的體驗,為開發人員提供無與倫比的生產力,並讓新創公司能夠從第一天起就將新想法推向整個可服務市場。

在之前的版本中,我們在 iOS 和 Android 的基礎上補充了 網頁Windows 支援,現在 Flutter 3 新增了對 macOS 和 Linux 應用程式的穩定支援。新增平台支援需要的更多是渲染像素:它還包括新的輸入和互動模型、編譯和構建支援、無障礙性和國際化,以及平台特定的整合。我們的目標是讓您能夠靈活地充分利用底層作業系統,同時根據需要分享盡可能多的 UI 和邏輯。

在 macOS 上,我們在支援 Intel 和 Apple Silicon 上投資了,並提供了 通用二進位檔 支援,允許應用程式封裝在兩種架構上都能原生執行的可執行檔。在 Linux 上,Canonical 和 Google 合作提供了高度整合的、最優的開發選項。

Superlist 是 Flutter 如何實現精美的桌面體驗的一個很好的範例,它今天以 beta 版推出。Superlist 提供超級加強的協作功能,透過一個新的應用程式將清單、任務和自由格式內容結合在一起,重新詮釋待辦事項清單和個人規劃。Superlist 團隊選擇 Flutter 是因為它能夠提供快速且高度品牌化的桌面體驗,我們認為他們迄今為止的進展證明了為什麼這是一個非常棒的選擇。

Flutter 3 還改進了許多基礎功能,包括改進的效能、Material You 支援和生產力更新。

除了上面提到的工作之外,透過這個版本,Flutter 在 開發 上完全原生於 Apple Silicon。雖然 Flutter 自從推出以來就一直與搭載 M1 的 Apple 設備相容,但 Flutter 現在充分利用了 Dart 對 Apple Silicon 的支援,使搭載 M1 的設備上的編譯速度更快,並支援 通用二進位檔 用於 macOS 應用程式。

我們對 Material Design 3 的工作在這個版本中已基本完成,讓開發人員能夠利用自適應的跨平台設計系統,該系統提供動態色彩方案和更新的視覺組件:

我們詳細的技術部落格文章將深入探討這些功能以及 Flutter 3 中的許多其他新功能。

Flutter 由 Dart 提供支援,Dart 是一種高生產力、可移植的語言,適用於多平台開發。我們在此週期的 Dart 工作包括新的語言功能,這些功能可以減少樣板程式碼並幫助提高可讀性、實驗性的 RISC-V 支援、升級的 linter 和新的文件。若要進一步了解 Dart 2.17 中的所有新改進,請查看 專門的部落格文章

Firebase 和 Flutter

當然,構建應用程式需要的不仅仅是 UI 框架。應用程式發行商需要一套完整的工具來幫助您構建、發佈和運行應用程式,包括身份驗證、資料儲存、雲端函數和裝置測試等服務。有多種服務支援 Flutter,包括 SentryAppWriteAWS Amplify

Google 的應用程式服務產品是 Firebase,SlashData 開發者基准研究 表明 62% 的 Flutter 開發人員在他們的應用程式中使用 Firebase。因此,在過去的幾個版本中,我們一直在與 Firebase 合作,將 Flutter 作為一級整合擴展和改進整合。這包括將 Flutter 的 Firebase Plugin 提升至 1.0 版本,新增更好的文件和工具,以及像 FlutterFire UI 這樣的新的 Widget,為開發人員提供可重複使用的 UI 用於身份驗證和檔案螢幕。

今天,我們宣布將 Flutter/Firebase 整合升級為 Firebase 提供的全功能核心部分。我們將原始碼和文件移至 Firebase 的主要存取庫和網站,您可以信賴我們會讓 Flutter 的 Firebase 支援與 Android 和 iOS 同步發展。

此外,我們對支援使用 Crashlytics(Firebase 受歡迎的即時崩潰報告服務)的 Flutter 應用程式進行了重大改進。透過 Flutter Crashlytics Plugin 的更新,您可以即時追蹤致命錯誤,為您提供與其他 iOS 和 Android 開發人員相同的功能集。這包括重要的警報和指標,例如「無崩潰使用者」,可以幫助您掌握應用程式的穩定性。Crashlytics 分析管道已升級,以改進 Flutter 崩潰的聚類,讓您可以更快地對問題進行分類、優先排序和修復。最後,我們簡化了 Plugin 安裝過程,因此您只需幾個步驟即可從 Dart 程式碼中啟動並運行 Crashlytics。

Flutter 休閒遊戲工具包

對於大多數開發人員來說,Flutter 是一個應用程式框架。但是,圍繞休閒遊戲開發的社群也在不斷增長,他們利用了 Flutter 提供的硬體加速圖形支援,以及像 Flame 這樣的開源遊戲引擎。我們希望讓休閒遊戲開發人員更容易入門,因此,在今天的 I/O 上,我們宣布 休閒遊戲工具包,它提供了一套包含範例和最佳實務的入門套件,以及廣告和雲端服務的信用額度。

雖然 Flutter 不是為高強度 3D 動作遊戲而設計的,但甚至一些這樣的遊戲也開始使用 Flutter 來處理非遊戲 UI,包括像 PUBG Mobile 這樣的熱門遊戲,該遊戲擁有數億使用者。為了讓 I/O 更上一層樓,我們想看看我們可以將技術推到什麼程度,因此我們製作了一個有趣的彈珠台遊戲,該遊戲由 Firebase 和 Flutter 的 Web 支援提供支援。I/O 彈珠台提供了一個自訂的桌子,設計圍繞著 Google 的四個最喜歡的吉祥物:Flutter 的 Dash、Firebase 的 Sparky、Android 機器人和 Chrome 恐龍,讓您可以與其他人競爭高分。我們認為這是一個展示 Flutter 多功能性的有趣方式。

由 Google 贊助,社群提供支援

我們喜歡 Flutter 的一點是,它不仅仅是 Google 的產品,它是「大家的」產品。開源意味著我們都可以參與其中,並在它的成功中發揮作用,無論是貢獻新的程式碼還是文件,建立賦予核心框架新能力的套件,撰寫書籍和培訓課程來教導他人,還是幫助組織活動和使用者群組。

為了展示社群的最佳一面,我們最近與 DevPost 合作,贊助了一項拼圖黑客挑戰賽,讓開發人員有机会透過重新構思經典的滑動拼圖來展示他們的技能。這證明了 Web、桌面和行動如何整合在一起:現在我們都可以透過網路或商店玩這些遊戲。

我們製作了這個影片來展示一些我們最喜歡的投稿和獲獎作品;我們認為您會喜歡的:

感謝您對 Flutter 的支援,歡迎來到 Flutter 3!


Introducing Flutter 3 was originally published in Flutter on Medium, where people are continuing the conversation by highlighting and responding to this story.

【文章內容使用 Gemini 1.5 Pro 自動產生】

深入了解最新版本,包括 macOS 和 Linux 穩定版本、效能提升等等!

是時候再次發佈 Flutter 穩定版本了——我們非常自豪地宣布 Flutter 3!僅僅三個月前,我們宣布了 Flutter 對 Windows 的支援。今天,我們很高興地宣布,除了 Windows 之外,Flutter 現在也穩定支援 macOS 和 Linux!

感謝 Flutter 貢獻者的辛勤工作,我們已合併了 5248 個 Pull Request!

我們在此版本中有一些令人興奮的消息要宣布,包括 Flutter 對 macOS 和 Linux 的支援更新、重大的效能提升、行動和 Web 更新——以及更多!此外,我們還有一些關於減少對舊版 Windows 支援的資訊,以及一小部分重大變更。好了,讓我們開始吧!

隨時準備好在所有桌面平台上投入生產

Linux 和 macOS 已達到穩定狀態,並包含以下功能:

階層式選單和對 macOS 系統選單列的支援

您現在可以使用 PlatformMenuBar Widget 在 macOS 上建立平台渲染的選單列,它支援插入僅平台選單,以及控制 macOS 應用程式選單中顯示的內容。

A user clicks a menu which shows submenus on Mac
階層式選單示範

在所有桌面平台上完全支援國際文字輸入

國際文字輸入,包括對使用文字輸入法編輯器 (IME)(例如中文、日語和韓語)的語言的支援,在所有三個桌面平台上都得到完全支援,包括 Sogou 和 Google 日語輸入等第三方輸入法。

所有桌面平台上的無障礙功能

Windows、macOS 和 Linux 的 Flutter 支援無障礙服務,例如螢幕閱讀器、無障礙導航和反色。

macOS 上預設為通用二進制檔案

從 Flutter 3 開始,Flutter macOS 桌面應用程式被建構為通用二進制檔案,原生支援現有的基於 Intel 的 Mac 和 Apple 最新推出的 Apple Silicon 設備。

棄用 Windows 7/8 開發

在此版本中,我們將推薦的 Windows 開發版本提升到 Windows 10。雖然我們沒有阻止在舊版本(Windows 7、Windows 8、Windows 8.1)上進行開發,但這些版本 不再受 Microsoft 支援,而且我們對這些版本的測試有限。雖然我們將繼續為舊版本提供「盡力而為」的支援,但我們鼓勵您升級。

**注意:**我們繼續提供對在 Windows 7 和 Windows 8 上 *運行* 的 Flutter 應用程式的支援;此更改僅影響推薦的開發環境。

行動更新

我們對行動平台的更新包括以下內容:

可折疊手機支援

Flutter 3 版本支援可折疊行動設備。在由 Microsoft 帶頭合作的過程中,新功能和 Widget 讓您可以在可折疊設備上建立動態且令人愉悅的體驗。

作為此工作的一部分,MediaQuery 現在包含一個 DisplayFeatures 清單,描述設備元素(如鉸鏈、摺疊和切口)的邊界和狀態。此外,DisplayFeatureSubScreen Widget 現在會將其子 Widget 定位在不與 DisplayFeatures 的邊界重疊的位置,並且已經與框架的預設對話方塊和彈出視窗整合在一起,使 Flutter 開箱即用 地感知和對這些元素做出響應。

非常感謝 Microsoft 團隊,尤其是 @andreidiaconu,他們的貢獻!

嘗試 Surface Duo 模擬器範例,其中包括一個帶有 Flutter 圖庫的特殊分支,以查看 Flutter 的雙顯示器在實際情況下的運行情況。

iOS 可變更新率支援

Flutter 現在支援具有 ProMotion 顯示器的 iOS 設備(包括 iPhone 13 Pro 和 iPad Pro)上的可變更新率。在這些設備上,Flutter 應用程式可以以高達 120 赫茲的更新率渲染,而之前限制為 60 赫茲。這在快速動畫(例如捲軸)期間產生更流暢的體驗。查看 flutter.dev/go/variable-refresh-rate 以獲取更多詳細資訊。

簡化的 iOS 發佈

我們已在 flutter build ipa 命令 中加入了新選項,以簡化 iOS 應用程式的發佈。當您準備好發佈到 TestFlight 或 App Store 時,運行 flutter build ipa 以建立 Xcode 檔案 (.xcarchive 檔案) 和應用程式捆綁 (.ipa 檔案)。您可以選擇性地加入 —-export-method ad-hoc、—-export-method development 或 —-export-method enterprise。建立應用程式捆綁後,透過 Apple Transport macOS 應用程式 或在命令列上使用 xcrun altool 將其上傳到 Apple(運行 man altool 以獲取 App Store Connect API 金鑰驗證指示)。上傳後,您的應用程式即可發佈到 TestFlight 或 App Store。在設定初始 Xcode 專案設定(如顯示名稱和應用程式圖標)後,您不再需要打開 Xcode 來發佈應用程式。

Gradle 版本更新

如果您使用 Flutter 工具建立新的專案,您可能會注意到,產生的檔案現在使用 Gradle 和 Android Gradle Plugin 的最新版本。對於現有的專案,您需要手動將 Gradle 的版本提升到 7.4,將 Android Gradle Plugin 的版本提升到 7.1.2。

停止支援 32 位 iOS/iOS 9/iOS 10

正如我們在 2022 年 2 月的 2.10 穩定版本中所宣布的那樣,Flutter 對 32 位 iOS 設備和 iOS 版本 9 和 10 的支援即將結束。此更改影響 iPhone 4S、iPhone 5、iPhone 5C,以及第 2 代、第 3 代和第 4 代 iPad 設備。Flutter 3 是最後一個支援這些 iOS 版本和設備的穩定版本。

若要進一步了解此更改,請查看 RFC:停止支援 32 位 iOS 設備

Web 更新

我們對 Web 應用程式的更新包括以下內容:

圖片解碼

Flutter 網頁現在會自動檢測並在支援它的瀏覽器中使用 ImageDecoder API。截至今天,大多數基於 Chromium 的瀏覽器(Chrome、Edge、Opera、Samsung Browser 等等)都加入了這個 API。

新的 API 使用瀏覽器的內建圖片編解碼器,在主執行緒之外異步地解碼圖片。這將圖片解碼速度提高了 2 倍,而且它永遠不會阻塞主執行緒,消除了之前由圖片引起的任何卡頓。

Web 應用程式生命週期

Flutter Web 應用程式的新生命週期 API 讓您能夠從託管的 HTML 頁面控制 Flutter 應用的引導過程,並幫助 Lighthouse 分析應用的效能。這適用於許多用例,包括以下常用的場景:

  • 啟動畫面。
  • 載入指示器。
  • 在 Flutter 應用之前顯示的純 HTML 互動式登陸頁面。

如需更多資訊,請查看 docs.flutter.dev 上的 自訂 Web 應用程式初始化

工具更新

我們對 Flutter 和 Dart 工具的更新包括:

更新的 lint 套件

lint 套件的 2.0 版本已發佈:

使用 flutter create 在 Flutter 3 中生成的應用程式會自動啟用 v2.0 的 lint 集合。鼓勵現有的應用程式、套件和 Plugin 透過運行 flutter pub upgrade –major-versions flutter_lints 遷移到 v2.0,以遵循 Flutter 世界中的最新最佳實務。

v2 中新增的大多數 lint 警告都帶有自動修復。因此,在將應用程式 pubspec.yaml 檔案中的套件升級到最新版本之後,您可以在程式碼庫上運行 dart fix --apply 以自動修復大多數 lint 警告(一些警告仍然需要手動操作)。尚未使用 package:flutter_lints 的應用程式、套件或 Plugin 可以透過遵循 遷移指南 來遷移。

效能提升

感謝開源貢獻者 @knopp,部分重新繪製已在支援它的 Android 設備上 啟用。在我們的本地測試中,此更改將 Pixel 4 XL 設備上 backdrop_filter_perf 基準測試的平均、第 90 個百分位數和第 99 個百分位數畫面柵格化時間減少了 5 倍。當存在單個矩形髒區域時,部分重新繪製現在已在 iOS 和更新的 Android 設備上啟用。

我們已 進一步改進 了簡單情況下不透明度動畫的效能。特別是,當 Opacity Widget 僅包含單個渲染原語時,Opacity 通常會調用的 saveLayer 方法被省略。在一項用於衡量此優化效益的基準測試中,這種情況下的柵格化時間 提高了一個數量級。在未來的版本中,我們計劃將此優化應用於更多場景。

感謝開源貢獻者 @JsouLiang,引擎的柵格化和 UI 執行緒現在在 Android 和 iOS 上比其他執行緒(例如 Dart VM 後台垃圾回收執行緒)擁有更高的優先級。在我們的基準測試中,這導致 平均畫面構建時間快了約 20%

在 3 版本之前,柵格快取的准入政策只查看圖片中的繪製操作數量,假設任何超過幾個操作的圖片都是快取的良好候選者。不幸的是,這導致引擎浪費記憶體來快取實際上渲染速度非常快的圖片。此版本 引入了一種機制,它根據圖片中包含的繪製操作的成本來估計圖片的渲染複雜度。使用此作為柵格快取准入政策,減少了記憶體使用量,而在我們的基準測試中沒有降低效能。

感謝開源貢獻者 @ColdPaleLight,他 修復了畫面排程中的錯誤,該錯誤導致 iOS 上有少量動畫畫面被丟棄。感謝每一位報告此問題並提供重現步驟和丟棄畫面的影片的人。

Impeller

團隊一直在努力尋找解決 iOS 和其他平台上早期卡頓的方法。在 Flutter 3 版本中,您可以在 iOS 上預覽一個名為 Impeller 的實驗性渲染後端。Impeller 在引擎構建時預編譯了 更小、更簡單的著色器集合,以便它們不會在應用程式運行時編譯;這是 Flutter 中卡頓的主要來源。Impeller 尚未準備好投入生產,而且還遠未完成。目前還未實作所有 Flutter 功能,但我們對其在 flutter/gallery 應用程式中的保真度和效能感到滿意,因此我們分享了我們的進展。特別是,圖庫應用程式轉場動畫中最差的畫面 快了約 20 倍

Impeller 在 iOS 上可以使用標記。您可以將 —-enable-impeller 傳遞給 flutter run,或者將 Info.plist 檔案中的 FLTEnableImpeller 標記設定為 true,以嘗試使用 Impeller。Impeller 的開發工作仍在 Flutter 的 master channel 上繼續進行,我們希望在未來的版本中提供更多更新。

Android 上的內嵌廣告

當您使用 google_mobile_ads 套件 時,您應該會在使用者關鍵互動(例如捲軸和頁面之間的轉場)中看到更好的效能。這在新興市場中流行的設備上尤其明顯。最棒的是,不需要進行任何程式碼更改!

在幕後,Flutter 現在會異步地組合 Android 視圖,通常稱為 平台視圖。這意味著 Flutter 柵格化執行緒不需要等待 Android 視圖渲染。相反,Flutter 引擎會使用它管理的 OpenGL 紋理將視圖放置在螢幕上。

更多令人興奮的更新

Flutter 生態系統的其他更新包括以下內容:

Material 3

Flutter 3 支援 Material Design 3,這是 Material Design 的下一代版本。Flutter 3 為 Material 3 提供了選擇性支援;這包括 Material You 功能,如動態色彩、更新的色彩系統和字體排版、對許多組件的更新,以及 Android 12 中引入的新的視覺效果,如新的觸控漣漪設計和拉伸過捲效果。在 新的 將您的 Flutter 應用程式從無聊變成漂亮 程式碼實驗室中嘗試 Material 3 功能。查看 API 文件 以了解如何選擇性使用這些新功能以及哪些組件支援 Material 3。透過 Material 3 總體議題 關注正在進行的工作。

主題擴展

Flutter 現在可以使用名為 主題擴展 的概念將 任何 內容加入到 material 函式庫的 ThemeData 中。您可以指定 ThemeData.extensions,而不是(在 Dart 中的意義上)擴展 ThemeData 並重新實作其 copyWith、lerp 和其他方法。此外,作為套件開發人員,您可以提供 ThemeExtension。查看 flutter.dev/go/theme-extensions 以獲取更多詳細資訊,並查看 GitHub 上的這個範例

廣告

我們知道,發佈者向使用者要求個人化廣告的同意並處理 Apple 的 App 追蹤透明度 (ATT) 要求非常重要。

為了支援這些要求,Google 提供了使用者訊息平台 (UMP) SDK,它取代了之前的開源 同意 SDK。在即將發佈的 Flutter 版 GMA SDK 中,我們將加入對 UMP SDK 的支援,以允許發佈者獲得使用者同意。如需更多詳細資訊,請查看 pub.dev 上的 google_mobile_ads 頁面。

重大變更

隨著 Flutter 的不斷成長和改進,我們旨在將重大變更的數量降至最低。在 Flutter 3 發佈時,我們有以下重大變更:

如果您正在使用任何這些 API,請參閱 Flutter.dev 上的遷移指南

總結

來自 Google 的 Flutter 團隊向您表示感謝,感謝社群做出的出色工作,幫助 Flutter 保持其作為最受歡迎的跨平台 UI 工具包的地位,正如 Statista 和 SlashData 等分析師所衡量的那樣。我們期待以社群為驅動的工具一起努力,繼續為開發人員和使用者提供令人愉悅的體驗!


Flutter 3 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。