0%

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

強勢開啓 2024:Flutter 和 Dart 的新篇章

我們興奮地宣布今年首個季度 Flutter 和 Dart 的 SDK 版本更新——Flutter 3.19 和 Dart 3.3,以及一些令人興奮的人工智慧相關消息。

Flutter 和 Dart 的價值與未來

我最近加入了 Flutter 和 Dart 團隊,我很高興能在 AI 迅速發展以提升開發人員生產力並解鎖新型使用者體驗的時刻,與我們的開發人員社群合作。我看到了 Flutter 和 Dart 在幫助塑造未來方面發揮的無限潛力。我同樣受到 Flutter 的最初願景的啟發,即改進為任何設備構建漂亮、高效、多平台應用程式的體驗。

從數百萬支援 Flutter 的才華橫溢且富有創造力的開發人員(他們為框架做出貢獻,或構建令人驚嘆的體驗)來看,很明顯,其他人也看到了這個願景,並有動力去幫助實現它。核心使命仍然相同:提供強大的語言架構配對,讓富有創造力的開發人員能夠為任何設備構建漂亮、豐富且高效能的應用程式。讓我們一起完成吧!

將 Flutter 和 Dart 帶入 Gemini 時代

今天,我們推出了 [Google AI Dart SDK](https://medium.com/flutter/harness-gemini-in-your-dart-and-flutter-apps-00573e560381),一個新的 pub.dev 套件,[google_generative_ai](https://pub.dev/packages/google_generative_ai),以及 [支援資源](https://ai.google.dev/tutorials/dart_quickstart);這些工具共同讓您可以使用 Gemini API 在 Dart 和 Flutter 應用程式中構建自己的基於生成式 AI 的功能,例如智慧聊天機器人、視覺搜尋引擎和圖片描述。Flutter 和 Dart 的跨平台功能以及這個新的 SDK 使您能夠更輕鬆地在不同平台上構建互動式體驗。

這僅僅是我們正在利用 AI 為 Flutter 和 Dart 開發帶來的創新浪潮的開始。例如,Flutter 和 Dart 開發人員很快就可以在 [Google 的 AI Studio](https://aistudio.google.com/?utm_source=flutter&utm_medium=referral&utm_campaign=blog_umbrella_announcement&utm_content=) 中完善您的用例提示後直接複製 Dart 程式碼。

在 [深入探討的部落格文章](https://medium.com/flutter/harness-gemini-in-your-dart-and-flutter-apps-00573e560381) 中了解更多關於 Google AI Dart SDK 的資訊。

許多開發人員已經開始以令人興奮的方式將 Flutter 和 AI 工具結合在一起:

  • LeanCode 團隊已使用 Gemini 模型構建了 [arb_translate](https://leancode.co/arb_translate),一個允許開發人員自動執行翻譯任務的套件。
  • We Spot Turtles! 將 Flutter 和 AI 結合到他們的使命中,旨在拯救海龜免於滅絕。他們最近被 Google Play 的 [WeArePlay 活動](https://play.google.com/console/about/weareplay/) 報導。請查看下面的影片。
  • AutoGPT,一個基於大型語言模型 (LLM) 的實驗性開源專案,擁有一個 [Flutter 客戶端](https://github.com/Significant-Gravitas/auto_gpt_flutter_client),可以在 iOS、Android、網頁、macOS 和 Windows 上運行。

[#WeArePlay | Caitlin and Nicolas | We Spot Turtles! | Australia](https://youtu.be/CfzhLOiczDQ?si=Qgc4Yb4Q9xKI6byF)

在您探索 Gemini 模型的功能時,請務必使用 #BuildWithGemini 標籤與我們分享您正在構建的全新且創新的體驗。

兩個新的 SDK 版本

除了 AI 帶來的興奮之外,我們仍然專注於持續構建一個強大的 UI 架構,它能夠交付您想要在任何想要構建的螢幕上構建的任何體驗。您會在今天的 SDK 版本 Flutter 3.19 和 Dart 3.3 中看到朝著這個願景的進展。

這些版本重點關注完善和效能改進,這些改進建立在 Flutter 和 Dart 去年 [設定的軌跡](https://medium.com/flutter/whats-next-for-flutter-b94ce089f49c) 之上。在此 Flutter 版本中,您將發現:

  • 對我們透過持續在 Impeller 上的工作來生成突破性圖形效能的努力進行更新。
  • 透過 Flutter iOS 原生字體和深層連結網頁驗證器的早期版本,朝向提供平台之間的無縫整合邁出更多步驟。
  • 持續關注開發人員體驗,包括對 DevTools 的更新和 [Flutter 套件生態系統進展報告](https://medium.com/flutter/progress-of-the-flutter-package-ecosystem-17cded9a0703?source=collection_home---4------1-----------------------)。
  • 最後,我們很高興分享我們在幫助定義 Web 未來的 Wasm 任務上的進展。

反過來,Dart 3.3 引入了擴展類型,一種與 Web 上的 JavaScript 互動的新模型,並且更新了我們對支援存取更多、更好的 Web 函式庫的工作。您可以在 [Flutter 3.19](https://medium.com/flutter/whats-new-in-flutter-3-19-58b1aae242d2) 和 [Dart 3.3](https://medium.com/dartlang/dart-3-3-325bf2bf6c13) 的部落格文章中分別了解更多關於每個版本的資訊。

2024 年策略與路線圖

這些功能中的每一個都是我們今年正在進行的一個更大旅程中的小小一步,您可以在我們的 [2024 年路線圖](https://github.com/flutter/flutter/wiki/Roadmap) 中看到。與往常一樣,這些路線圖源於我們希望公開我們的計劃的願望,因為我們知道你們中的許多人將 Flutter 和 Dart 視為職業和業務中必不可少的組成部分。話雖如此,即使制定了計劃,進展也很難預測。

雖然我們將盡最大努力繼續保持透明度,因為不可避免的變化會迫使我們轉移重點並做出取捨,但我們想強調,在 Google 之外,Flutter 和 Dart 的貢獻者比我們在這裡工作的員工還要多,這意味著我們的路線圖中提到的內容僅僅是今年 Dart 和 Flutter 將發生的數千次變更中的一小部分。

2024 roadmap

將所有內容整合在一起

我在 Google 和 YouTube 的 17 年多的時間裡參與過許多有趣且創新的專案,但這是對新的機會感到最熱情的時刻。我從軟體工程師開始我的職業生涯,我在 Google 的第一份工作是地圖 API 和地理開發者工具的產品經理,因此能夠回到我的開發人員根源真是太好了。

推動我熱情的一部分是,嗯,您的熱情。僅僅在 2024 年,我看到了這個社群取得了如此令人驚嘆的成就,包括:

  • 超過 2,700 位開發人員加入了我們的 [全球遊戲挑戰](http://flutter.dev/global-gamers),這是我們與國際倡導機構 Global Citizen 合作舉辦的,旨在挑戰您利用自己的技能構建 Flutter 遊戲,激勵世界以更可持續的方式生活。
  • [Superlist](https://youtu.be/37qvcjmE51w),在昨天宣布了 1.0 版本,正在使用 Flutter 重塑任務管理、筆記記錄以及介於兩者之間的一切。

最後,我的孩子們正在學習電腦科學,我致力於幫助創造軟體開發體驗,幫助下一代為更美好的世界做出改變。

今年對於創造這樣的未來來說至關重要,我迫不及待地想看看 Flutter 和 Dart 如何支援它。與往常一樣,我們非常感謝您持續的支持,我們迫不及待地想看看我們將共同創造的成果。下次再見!


強勢開啓 2024:Flutter 和 Dart 的新篇章 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

分享 Flutter 2024 年的路線圖

作為一個擁有蓬勃發展的社群的開源專案,我們致力於對我們的計畫保持透明,從問題到設計規格,所有內容都在公開場合分享。我們聽到了許多人對 Flutter 功能路線圖的興趣。這些路線圖在可預測性方面可能會很困難,因為這些計畫往往會在全年調整和適應,但我們仍然認為分享我們的整體計畫很重要,並帶有以下聲明:計畫可能會改變。

我們一直在發佈我們的路線圖,從 2020 年開始,而今天我們將分享我們的 2024 年路線圖。這是對前幾年工作的自然延續,我們仍然致力於我們的長期目標,即打造 *最受歡迎、成長最迅速、生產力最高的跨平台 UI 架構,用於建立豐富的應用程式體驗*。

請注意,我們在此列出的内容主要來自那些作為 Google 員工在 Flutter 上工作的我們。到目前為止,非 Google 貢獻者的數量已超過 Google 員工,因此這並不是我們希望今年在 Flutter 中出現的所有新事物和令人興奮事物的詳盡清單!

我們對社群和您的持續支持表示衷心的感謝。我們迫不及待地想看看您將建立什麼!


分享 Flutter 的 2024 年路線圖 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

Dart 3.3 來了,帶來效能和跨平台開發的重大變革!

Dart 3.3 已經推出,它將徹底改變效能和跨平台開發! 準備好使用 擴展類型 為您的應用程式增強能量,徹底改變效能優化,以及您與原生程式碼互動的方式。此外,我們改版後的 JavaScript 互操作 模型引入了強大的類型安全性,以及一種開發人員友好的方式來利用 Web 平台的強大功能。所有這些都為 WebAssembly 支援鋪平了道路。哦,還有 在您的 Dart 應用程式中使用 Google AI?當然可以!這一切都在 Dart 3.3 中。讓我們深入了解!

介紹擴展類型

擴展類型為類型引入了零成本封裝。使用它們來優化效能敏感的程式碼,特別是在與主機平台進行互操作時。擴展類型提供了自訂類型的便利性,這些自訂類型具有特定的成員,同時消除了典型的封裝分配開銷。

1
2
3
4
5
6
7
8
9
10
extension type Wrapper(int i) {
void showValue() {
print('my value is $i');
}
}

void main() {
final wrapper = Wrapper(42);
wrapper.showValue(); // Prints 'my value is 42'
}

以上範例將 Wrapper 定義為擴展類型,但將其用於像一個簡單的 Dart 類型。您可以實例化它並呼叫函數。Dart 將其編譯為一個正常的 Dart int,這才是關鍵的差別。擴展類型允許您在不產生分配典型封裝類型的間接成本的情況下,建立一個具有獨特成員的類型。因此,雖然 擴展成員 功能(自 Dart 2.7 以來可用)允許您為現有類型新增函數和屬性,但擴展類型功能可以做同樣的事情,而且還可以 定義一個隱藏底層表示的新 API。

這對於與主機平台的互操作性特別有用。原生類型可以直接使用,而無需建立封裝器和相關的間接成本,同時仍然提供乾淨的生產 Dart API。在 新的擴展類型文件 中了解更多資訊。

改進 JavaScript 互操作

Dart 3.3 引入了一個新的模型,用於與 JavaScript 函式庫和 Web 進行互操作。它從一組與 JavaScript 互動的新 API 開始:dart:js_interop 函式庫。現在 Dart 開發人員可以使用類型化的 API 與 JavaScript 進行交互。此 API 清晰地定義了兩種語言之間的界限,並進行了靜態強制。這消除了 編譯時間之前的一整類問題。除了存取 JavaScript 程式碼的新 API 之外,Dart 現在還包括一個使用擴展類型在 Dart 中表示 JavaScript 類型的模型。

1
2
3
4
5
6
7
8
9
import 'dart:js_interop';

/// Represents the `console` browser API.
extension type MyConsole(JSObject _) implements JSObject {
external void log(JSAny? value);
external void debug(JSAny? value);
external void info(JSAny? value);
external void warn(JSAny? value);
}

基於擴展類型的語法允許比擴展成員更具表現力和健全性。這簡化了從 Dart 利用 JavaScript API。在 新的 JS 互操作文件 中了解更多資訊。

改進瀏覽器函式庫

自 1.0 版本以來,Dart SDK 已包含一組全面的瀏覽器函式庫。其中包括核心 dart:html 函式庫,以及用於 SVG、WebGL 和其他功能的函式庫。

改進的 JavaScript 互操作模型提供了重新構想這些函式庫的機會。展望未來,我們的瀏覽器函式庫支援將專注於 package:web。這簡化了版本控制,加速了更新,並與 MDN 資源保持一致。

這條改進鏈引導我們走向下一件大事:將 Dart 編譯為 WebAssembly

立即開始,為 WebAssembly 的未來做好準備

有了 Dart 3.3,套件和應用程式作者可以為編譯為 WebAssembly 的 Web 應用程式奠定基礎。雖然 Flutter Web 中的 WebAssembly 支援仍然是實驗性的,但團隊正在努力穩定實作。若要使用 WebAssembly 在 Web 上運行 Flutter 應用程式,您需要遷移所有程式碼——從應用程式和所有相依項——以使用新的 JavaScript 互操作機制和 package:web。傳統的 JavaScript 和瀏覽器函式庫保持不變,並支援編譯為 JavaScript 程式碼。但是,編譯為 WebAssembly 需要遷移。

我們創建了一個 遷移指南 來幫助作者開始包含 Wasm。我們希望在將其納入穩定版本時,最受歡迎的套件都支援 Wasm。

另外一件事:介紹 Google AI Dart SDK

Google 已將 Google AI Dart SDK 發佈到測試版。您可以將生成式 AI 功能構建到您的 Dart 或 Flutter 應用程式中。這些應用程式使用 Gemini,這是 Google 最新一代的 AI 模型。查看 package:google_generative_ai。在 這篇部落格文章 中了解如何使用 Google AI Dart SDK 進行構建,或者直接跳到 快速入門


Dart 3.3 的新功能:擴展類型、JavaScript 互操作等等 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

undefined

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

介紹 Google AI Dart SDK

我們很興奮地宣布推出 Google AI Dart SDK,用於 Gemini API。新的 pub.dev 套件,google_generative_ai,以及 支援資源 讓您可以透過與 Gemini API 的慣用 Dart 整合,將您自己的基於生成式 AI 的功能建立到 Dart 和 Flutter 應用程式中。它為從單一程式碼庫為 Android、iOS、網頁、macOS、Windows 和 Linux 建立智慧、高效能的應用程式開闢了廣泛的可能性。

使用 Google AI Dart SDK,您可以:

  • 輕鬆整合生成式 AI 功能:透過最少的設定,將進階文字生成、摘要、聊天等功能添加到您的 Dart 或 Flutter 應用程式中。
  • 利用 Google 目前最具能力和通用性的模型:Gemini 模型汲取了 Google 在機器學習方面的廣泛研究和開發成果,讓您可以使用持續改進的生成式 AI 功能。
  • 加速您的 AI 驅動應用程式開發:專注於您的應用程式邏輯和使用者體驗,而 SDK 則處理與 AI 模型互動的複雜細節。
  • 建立跨平台的 AI 驅動應用程式:使用 Flutter,輕鬆地在桌面、網頁和行動應用程式中建立生成式 AI 功能。
  • 在 180 多個國家和地區使用 Gemini API:查看 可用區域 以獲取 Gemini API 和 Google AI Studio(以下將進一步說明)目前可用的國家和地區清單。

您可以建立什麼?

我們相信生成式 AI 具有巨大潛力,可以幫助您實現應用程式和業務目標。由於 Gemini 模型是多模態的(它能夠處理來自多種方式的資訊,包括圖片和文字),因此它讓您發揮極大的創造力。然而,我們經常從應用程式開發人員那裡(甚至從我們自己的團隊內部)得到的第一个問題是「我實際上可以使用 Gemini API 做些什麼?」以下是一些您可能為您的 Dart 或 Flutter 應用程式建立的功能範例:

  • 文字摘要:從文字輸入中生成長文章、研究論文或網站內容的簡潔摘要。
  • 智慧聊天機器人:建立更具吸引力且更像人類的對話介面,增強您的應用程式中的使用者體驗。
  • 視覺搜尋引擎:使用者可以上傳圖片,應用程式使用 Gemini API 傳回圖片中內容、樣式,甚至如何製作圖片中內容的描述。
  • 為無障礙使用生成圖片描述:生成上傳圖片的詳細文字描述,以幫助視障使用者。
  • 圖表和圖表解析:使用者可以上傳圖表、圖表或圖形的圖片,Gemini API 可以提供資料的文字分析和說明。

這個清單可以一直列下去,因為可能性幾乎是無限的!

A screenshot of the Flutter sample app that uses the Google AI Dart SDK
使用 Google AI Dart SDK 的 Flutter 範例應用程式的螢幕截圖

入門

查看 Dart 快速入門 以獲取有關如何建立設定的詳細分步指南。總體而言,以下是您將執行的操作:

  1. 從 Google AI Studio 獲取 Gemini API 金鑰。確保此金鑰安全。我們強烈建議您不要將金鑰直接包含在您的程式碼中,也不要將包含金鑰的文件检入版本控制系統。在開發過程中,我們建議使用 flutter run -d [DEVICE NAME] — dart-define=API_KEY=[YOUR API KEY] 在模擬器/模擬器中運行應用程式,使用您的 API 金鑰作為環境變數。
  2. 透過分別運行 dart pub add google_generative_aiflutter pub add google_generative_ai,將 Google AI Dart SDK 添加到您的 Dart 或 Flutter 應用程式中。這會將 google_generative_ai 添加為 pubspec.yaml 檔案中的相依性。
  3. 在您的程式碼中初始化生成式模型:
1
2
3
4
5
6
7
8
9
10
import 'package:google_generative_ai/google_generative_ai.dart';

// 將您的 API 金鑰作為環境變數存取(見上述第一步)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No $API_KEY environment variable');
exit(1);
}

final model = GenerativeModel(model: 'MODEL_NAME', apiKey: apiKey);
  1. 現在您可以開始探索使用 Gemini API 實作不同的用例。例如,當提示輸入包含文字和圖片時,使用 gemini-pro-vision 模型和 generateContent 方法,以生成文字輸出:
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
import 'dart:io';

import 'package:google_generative_ai/google_generative_ai.dart';

void main() async {
// 將您的 API 金鑰作為環境變數存取(見上述第一步)
final apiKey = Platform.environment['API_KEY'];
if (apiKey == null) {
print('No $API_KEY environment variable');
exit(1);
}
// 對於文字和圖片輸入(多模態),使用 gemini-pro-vision 模型
final model = GenerativeModel(model: 'gemini-pro-vision', apiKey: apiKey);
final (firstImage, secondImage) = await (
File('image0.jpg').readAsBytes(),
File('image1.jpg').readAsBytes()
).wait;
final prompt = TextPart("What's different between these pictures?");
final imageParts = [
DataPart('image/jpeg', firstImage),
DataPart('image/jpeg', secondImage),
];
final response = await model.generateContent([
Content.multi([prompt, ...imageParts])
]);
print(response.text);
}

探索 Gemini API 文檔,並查看 GitHub 儲存庫中的 Dart 和 Flutter 範例應用程式,以獲取有關如何為各種用例使用 SDK 的詳細指南和範例,或者在 DartPad 中的此範例應用程式 中查看,DartPad 是用於 Dart 和 Flutter 片段的免費開源線上編輯器,現在使用 Flutter 建立。請在 generative-ai-dart GitHub 儲存庫 中報告任何問題,或告訴我們有關功能要求。

Google AI Studio

除了 SDK 之外,Google AI Studio 是一個基於瀏覽器的 IDE,用於使用生成式模型進行原型設計。它讓您可以快速迭代以開發用例的提示,然後獲取 API 金鑰以在您的應用程式開發中使用。您可以使用您的 Google 帳戶登入 Google AI Studio,並利用免費配額,允許每分鐘 60 次請求。為了幫助我們提高產品品質,當您使用免費配額時,您的 Google AI Studio 輸入和輸出可能會被訓練有素的審閱者存取。這些資料會與您的 Google 帳戶和 API 金鑰脱钩。

我們將很快將 Dart 添加到 Google AI Studio,請密切關注我們的公告!這將讓您可以簡單地點擊「取得程式碼」,選擇新的 Dart 標籤(它將與現有支援的語言並列),然後「複製」Dart 程式碼以將您的工作傳輸到您選擇的 IDE。

A screenshot of Google AI Studio
Google AI Studio

分享您的成果!

我們期待看到您使用 Gemini 建立的成果,例如 LeanCode 團隊使用 Gemini API 建立的 arb_translate。它是一個套件,可以幫助開發人員自動執行語言翻譯,簡化 Flutter 應用程式中的本地化。

在 Twitter/X 上使用標籤 #BuildWithGemini 告訴我們您正在建立什麼!


在您的 Dart 和 Flutter 應用程式中利用 Gemini API 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

Flutter極致UI適應性:Google Earth如何支援地球上所有用例

當Google Earth準備以Flutter重寫其行動和網頁客戶端時,他們知道他們希望讓所有使用者都能以他們喜歡的方式探索地球,無論他們使用的是哪種設備。這在一定程度上一直是他們的目標;畢竟Google Earth已經擁有現有的網頁、桌面、Android和iOS客戶端。但這次重寫,將涵蓋除了桌面之外的所有目標,需要支援現有用例的超集;再加上Earth團隊渴望探索的一些新的適應性想法。

Google Earth未來技術堆栈的搜尋,受到了他們現有客戶端發展速度緩慢的摩擦來源的嚴重影響。也就是說,Google Earth很早就被迫在開發新功能的速度,以及在三個獨特的程式碼庫(網頁、Android和iOS)中維持功能一致性之間做出選擇。幸運的是,UI的中心——螢幕中央的整個淡藍色點——是由一個C++引擎驅動的,該引擎已經為Google Earth的一些功能提供了統一的體驗。然而,其餘的UI邊框和選單是在每個程式碼庫中單獨實現的。這意味著任何跨平台的選擇,不僅需要徹底改革UI開發流程,還需要與Android、iOS和網頁中的一個大型遺留引擎整合。

選擇使用Flutter的決定因素是雙重的。首先,使用方法通道與現有的Google Earth引擎整合證明是一項簡單的任務。其次,Google Earth不僅希望簡化他們的程式碼庫,還希望徹底重新設計他們的UI。任何重大的UI改版本身就是一種重寫,Google Earth選擇寫一個新的Flutter應用程式,而不是對三個現有應用程式進行手術。這使任務更加複雜,但團隊承諾要徹底改變,並專注於適應性。最後,Google Earth團隊使用Flutter來為三個平台提供UI。

定義適應性

於是,Google Earth團隊踏上了一段旅程,致力於突破UI適應性的極限。在創造符合不同使用者流程的UI方面,先前的經驗比比皆是——回溯到智慧型手機的黎明時期,以及整個網路集體意識到大多數網站都需要針對小螢幕重新設計。瀏覽器API和CSS模式出現了,以構建能夠感知螢幕解析度的網站;這些想法從那以後一直很突出。甚至在Flutter的最早期,開發人員都知道手機螢幕會有所不同,並讓他們應用程式的UI依賴於螢幕的解析度。如果解析度發生變化——無論是使用者旋轉手機還是調整瀏覽器視窗的大小,應用程式的UI都會做出反應。在Flutter中,就像在它之前的網頁中一樣,響應式UI 改善了使用者體驗。

那麼,您可能會好奇,響應式UI和適應性UI之間有什麼區別?簡而言之,響應式UI會根據可用像素的數量和長寬比調整;而適應性UI則會根據所有其他因素進行調整。響應式UI可以根據螢幕空間詳細資訊調整個別UI元素的大小,但適應性UI會回答更根本的問題,例如在哪裡渲染應用程式的導航、列表視圖是否應該導航到單獨的詳細視圖,還是與列表本身並排顯示,以及使用者連接的周邊設備如何影響點擊目標和懸停狀態等因素(稍後將詳細介紹此概念)。

若要進一步了解,請觀看 [Decoding Flutter 的第 15 集](https://youtu.be/HD5gYnspYzk?si=8AvuBRGXNRNET9dR) 關於適應性與響應式UI,並查看來自 [Flutter](https://docs.flutter.dev/ui/layout/responsive/building-adaptive-apps) 和 [Android 文件](https://developer.android.com/develop/ui/views/layout/responsive-adaptive-design-with-views)的這些指南。

任何曾經為網站撰寫響應式CSS的人都會告訴您,即使是最簡單的UI也可能帶有棘手的邊緣情況。明確地說,這不是CSS的錯;問題空間的許多狀態都非常細緻,幾乎感覺像模擬的。那麼,在考慮幾個額外的變數(例如設備形式因素和連接的周邊設備)時,UI開發人員應該期待什麼?當然,他們應該期待複雜性適當增加。

當一個早期原型表現出意外的行為時,這一切就都集中起來了。在玩那個早期版本時,一位Google Earth工程師將他們的桌面網頁瀏覽器縮小到一個非常窄的寬度。突然之間,常見的桌面功能(例如側邊導航欄和較小的點擊目標)被行動功能所取代,例如底部導航欄和更大、更適合手指的按鈕。他們的驚訝是短暫的——畢竟,這正是他們告訴他們的應用程式要做的。Google Earth團隊現在面臨一個深刻的問題——這是一個使用者想要的嗎?

這正是Google Earth團隊即將探索的未知領域。

為什麼要適應性?

對某些人來說,以下內容提出了一個元問題:為什麼要費盡心思做這些事情?當響應式UI肯定能滿足大多數使用者時,投資報酬率是否足夠?

這些都是好問題,但它們不應該導致對Flutter猶豫不決。使用像Flutter這樣的跨平台UI框架並不會引入適應性UI問題;它解鎖了適應性UI解決方案。除此之外,以下兩個因素表明適應性UI確實非常重要:

  • 螢幕解析度不再像以前那樣有意義。桌面瀏覽器可能具有低DPI設定,而基本的斷點檢查會將其與行動環境混淆;橫向模式下的高DPI手機可能會被誤認為是舊的平板電腦(甚至桌面!)斷點;而可摺疊設備可以交替顯示您的應用程式全螢幕,以及在多個應用程式之間分割螢幕空間,如果這導致使用者在某些斷點之間來回切換,就會導致令人不快的差異。
  • 帶有明顯創建與使用模式的應用程式(想想任何具有閱讀和編輯體驗的文字編寫應用程式)在行動裝置上可能會嚴重受到影響——特別是在平板電腦上。將以行動裝置為中心的體驗(可能以使用為中心)發佈到智慧型手機和平板電腦上,極大地限制了具有平板電腦、藍牙鍵盤和滑鼠的強大使用者。

實現適應性

Google Earth團隊經歷了漫長的實驗、使用者研究和迭代過程,才完成了最終發佈的應用程式。但最終,他們的問題空間歸結為三個高級問題:

  1. 應用程式如何確定其初始UI策略?
  2. 應用程式如何以及何時應更改其UI策略?
  3. Google Earth團隊如何清晰地實作此邏輯?

確定初始UI策略

Earth團隊的早期假設之一是「具有觸控螢幕的Chromebook與具有連接藍牙鍵盤的平板電腦之間沒有區別」,並且他們的UI不應該區分這兩種設備。雖然這個想法最初是有道理的,但它在測試中沒有存活下來;隨著時間的推移,Earth團隊越來越意識到這種方法的不足之處。以橫向模式啟動應用程式的使用者,可能會發現自己處於桌面UI的像素解析度範圍內(遵循舊的響應式UI規則)。如果同一位使用者隨後將他們的平板電腦旋轉成縱向模式,並因此轉移到分配給平板電腦的像素解析度範圍,Google Earth將面臨一個艱難的選擇。動態選項將是透過從桌面UI轉換到行動UI來大幅重組所有內容;而靜態選項將是除了將桌面UI壓縮和壓縮,直到它適合新的約束條件之外,什麼都不做。這兩種選項都不令人滿意,這意味著具有觸控螢幕的Chromebook和具有鍵盤的平板電腦之間確實有差異。

最終,Earth團隊設定了一個簡單的規則:為智慧型手機和平板電腦提供行動體驗,為桌面提供桌面體驗。如果這看起來很平淡無奇,那麼,它確實是;但這僅僅是因為它將一些有趣的部分推遲到了下一個問題——UI的初始策略何時應該 更改?

在使用者會話中更新UI策略

Earth團隊的UI更改的第一個策略,僅僅是已建立的響應式UI規則:在任何低於最低門檻值的解析度上顯示您的行動UI,在接下來的幾百種可能的寬度上顯示您的平板UI(如果您有),最後,在任何其他解析度上顯示您的桌面UI。而且,至關重要的是,當UI由於任何原因跨越了其中一個門檻值時,您會相應地重新渲染應用程式。當然,這個規則集的笨拙讓Google Earth開始了它的極致適應性之旅;因此,團隊放棄這種方法也就不足為奇了。

第二種可能性來自Stadia,一個具有成功的Flutter行動應用程式的Google團隊。(顯然,Stadia作為一種產品沒有存活下來;但这并非因为其行動應用程式缺乏功能!)Stadia的方法是根據最後觸摸的輸入來做出適應性UI決定。拖動電腦游標或按下鍵盤,Stadia就會切換到桌面UI模式。相反,如果您傾斜連接的主機控制器上的搖桿,Stadia就會切換到主機UI模式。但是,雖然這對Stadia來說有道理,但它被證明對Google Earth來說不太合適。一個簡單的案例排除了這種最後觸摸輸入策略:一個平板電腦使用者縮放地圖,然後回到藍牙鍵盤完成輸入內容。沒有使用者會希望在這種簡單的互動過程中發生兩次劇烈的UI轉換,因此使用者的最新輸入不能將Google Earth的UI從行動裝置切換到桌面或反之。

最終,Google Earth團隊設定了第二個非常簡單的規則:在一個會話中保持一致,並且在沒有使用者明確許可的情況下,絕不離開初始UI風格。如前所述,Google Earth會在智慧型手機和平板電腦上顯示其以行動裝置為中心的UI,在桌面電腦上顯示其以桌面為中心的UI;並且它絕不會自作聰明地更改此設定,除非使用者在設定面板中請求更改。

混合式UI狀態

在會話中保持UI一致對Google Earth很有幫助,但這並不是全部。桌面體驗中的UI功能(例如游標懸停效果)在行動裝置上沒有任何對應部分,必須重新設計。將觸控螢幕筆電當作平板電腦使用的使用者,可能會因應用程式未能將重要的懸停效果替換為適合行動裝置的替代方案而完全被阻擋。這種認識表明了一個兩層次的問題和解決方案。Google Earth的UI不僅需要在使用者請求時在行動和桌面體驗之間平滑地切換,而且個別控制項需要同時具有觸控友好的形式滑鼠友好的形式,無論整體策略如何。

最後,Google Earth知道他們在建立什麼。他們的所有研究和迭代只留下實作問題,這些問題歸結為:

  1. 如何管理兩個根本不同的UI之間的轉換,以及
  2. 如何建立支援非典型周邊設備的個別控制項

管理多個UI

簡單來說,建立任何可以在兩個不同體驗之間無縫切換的Flutter應用程式,就像在Widget的build方法中的某處放置以下程式碼一樣簡單:

1
child: mode == Mode.desktop ? DesktopUI() : MobileUI()

但是,這種策略(Google Earth使用的策略)意味著在其他地方需要做一些額外的工作才能完全實現。問題——最初是隱藏的——當任何應用程式狀態儲存在Stateful Widget中時就會浮出水面,因為切換mode變數會完全替換Widget樹,破壞所有狀態物件及其所持有的任何資訊。這個問題分為兩個層次。

要想像第一層,請考慮一個在桌面電腦上有多個面板的螢幕,但在行動裝置上將這些面板重新組織成一個標籤欄體驗。行動裝置使用者將有一個活動標籤,但這個概念在桌面電腦上沒有對應部分。將活動標籤索引儲存在StatefulWidget中(這是Flutter中的慣用方式!),會在透過桌面UI來回切換後,始終將行動裝置使用者的位置重置為預設標籤。解決這個問題的方法是將任何原始應用程式狀態——字串、整數等等——從StatefulWidget中移到您的狀態管理類別中。這樣一來,Widget樹中的任何惡作劇都不能重置關鍵的數值。

問題的第二層來自應用程式狀態,這些狀態很難從Widget樹中提取出來,例如TextEditingController或ScrollController。情況看起來像這樣:您有一個帶有TextField的ListTile,但每次使用者觸摸他們的滑鼠或觸控螢幕時,您都會重新建立該ListTile以適應使用者的最新周邊設備。如果沒有干預,這會導致Flutter破壞包含舊TextField的Widget和Element樹的整個部分,並將任何持有使用者工作的控制器一起帶走。您可能會想將這些視為原始資料(TextEditingController作為字串和ScrollController作為雙精度數),並重複上述解決方案;但控制器太豐富了,無法以這種方式輕鬆序列化(游標位置和文字選擇,誰知道呢?)。

為了解決這個問題,Google Earth使用GlobalKeys來讓框架在重新佈局後「重新為高度限定範圍的Widget指定父元素」。下面的AdaptableTextInput Widget嚴格限定在它的TextField和TextEditingController中。在UI更改重新建立過程中為AdaptableTextInput Widget提供相同的GlobalKey,將使TextEditingController保持有效,從而儲存使用者的工作。

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
class AdaptableTextInput extends StatefulWidget {

// 在這裡提供一個一致的 GlobalKey!
const AdaptableTextInput({super.key, required this.mode});

final Mode mode;

@override
State<AdaptableTextInput> createState() => _AdaptableTextInputState();
}

class _AdaptableTextInputState extends State<AdaptableTextInput> {

final _controller = TextEditingController();
final String helpText = '我說明這個文字輸入!';

@override
Widget build(BuildContext context) {
if (widget.mode == Mode.desktop) {
return Tooltip(
showOnHover: helpText,
child: TextField(controller: _controller),
);
} else if (widget.mode == Mode.mobile) {
return Column(
children: <Widget>[
TextField(controller: _controller),
Text(helpText);
],
);
}
}
}

導航

導航堆栈和應用程式的返回按鈕也需要特別注意。繼續以上面的桌面UI的例子來說,該UI一次顯示多個面板,現在想像一個互補的行動UI,它以堆栈式UI呈現這些面板,並具有向前和向後導航。允許桌面使用行動UI,以及手機使用桌面UI,是Google Earth想要追求的重要適應性理念之一。

UI的網格,顯示桌面設備上的桌面UI和行動裝置UI,以及行動裝置上的桌面UI和行動裝置UI

如果桌面UI使用者在切換到行動UI時位於紅色面板上,返回按鈕將不會自動連接,因為導航堆栈將被重置。這意味著您的桌面UI需要考慮額外的技術資訊,這些資訊僅供行動UI使用,因為行動UI隨時可能被要求接管。

一個桌面設備以兩種不同的模式渲染相同的UI——一種是典型的桌面模式,一種是典型的行動裝置模式

幸運的是,GoRouter 的宣告式路由 API 可以提供幫助。建立兩個單獨的路由宣告,並在使用者切換UI模式時切換到適當的路由。在這種情況下,如果桌面UI在收到啟動行動UI的請求時,已將使用者的最後活動追蹤到紅色面板,則呼叫mobileRouter.go('home/blue/red')將建立一個帶有合成歷史的導航堆栈,允許使用者按下返回按鈕退出紅色螢幕。

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
35
36
37
final desktopRouter = GoRouter(
routes: [
GoRoute(
path: '/home',
builder: (context, state) => FourPanels(),
),
],
);

final mobileRouter = GoRouter(
routes: [
// 每个面板一个路由,配置为连接返回按钮
// 如果用户到达其中一个嵌 入面板
GoRoute(
path: '/home/blue',
builder: (context, state) => BluePanel(),
routes: [
GoRoute(
path: 'red',
builder: (context, state) => RedPanel(),
routes: [
GoRoute(
path: 'green',
builder: (context, state) => GreenPanel(),
routes: [
GoRoute(
path: 'yellow',
builder: (context, state) => YellowPanel(),
),
],
),
],
),
],
),
],
);

像Google Earth這樣的適應性很強的UI需要一種實作,將所有可能的情況視為始終處於活動狀態,即使只渲染了特定的UI。這意味著應用程式必須始終能夠從您完全控制的資源中完全重建其狀態——無論是您是否有GlobalKeys來保留持有重要資訊的狀態物件,還是您已將所有相關詳細資訊儲存在狀態管理類別中。

適應使用者輸入

這只留下了一個棘手的適應性問題:確保UI中的控制項能够适应使用者的最后使用的外围设备,而不仅仅是当前有效的UI策略。毕竟,如果一个平板电脑用户开始点击蓝牙鼠标; Google Earth不会将UI整体切换到桌面模式,但他们确实想要稍微调整一些元素,以利用键盘和鼠标的优势。

仅仅使用Flutter意味着Google Earth在这方面已经取得了良好的开端。想象一下另一种情况:一个应用程序跨越三个代码库(JavaScript用于通过网页访问桌面,Swift和Kotlin用于移动设备),当Swift和Kotlin团队意识到如果在某些情况下,他们可以从JavaScript应用程序的UI中借用元素,那就太好了。也许他们需要的可以被简单地重新实现; 也许不行。无论哪种方式; 在一个Flutter应用程序中,您想要借用的现有工具始终位于同一个代码库中。

但是代码共享不是代码组织,如何连贯地实现这个问题仍然存在。在这里,Google Earth团队转向了一个老的Flutter主打工具:构建器模式。

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
/// 用户输入的高级类别。
enum InputType { gamepad, keyboardAndMouse, touch }

/// 构建一个依赖于用户当前[InputType]的widget树。
class InputTypeBuilder extends StatelessWidget {
/// 当[InputType]数据更新时调用。
final Function(BuildContext, InputTypeModel, Widget?) builder;

/// 构建一个包装widget,只要[InputType]
/// 改变就会调用[builder]。
///
/// 有关如何更改[InputType]的详细信息,请参见[InputTypeModel]。
const InputTypeBuilder({
Key? key,
required this.builder,
}) : super(key: key);

@override
Widget build(BuildContext context) {
return Consumer<InputTypeModel>(
builder: (context, inputTypeModel, _) {
return builder(
context,
inputTypeModel.inputType,
);
},
);
}
}

InputTypeBuilder这样的Widget会监听一个顶层机制,即InputTypeModel,它本身会订阅Flutter引擎以接收有关最后使用的输入的更新。InputTypeModel.inputTypeInputType枚举的属性。有了它,子Widget就可以根据用户当前与应用程序的交互方式做出本地化决策,决定如何渲染自身。例如,如果您一直在使用鼠标,但随后用手指点击了触摸屏,以前只有在鼠标悬停时才会出现的可视提示现在会在整个应用程序中显示。同样地,如果您切换回使用鼠标,这个InputTypeBuilder将允许他们撤销更改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@override
Widget build(BuildContext context) {
return InputTypeBuilder(
builder: (context, inputTypeModel, child) {
final bool isHoveredOrTouchInput = isHovered || inputTypeModel.inputType == InputType.touch;
return Row(
children: <Widget>[
isHoveredOrTouchInput ? DragIndicator() : Container(),
RestOfRow(),
],
);
},
);
}

以下GIF显示了Google Earth 的桌面UI(在Chrome中运行),巧妙地适应了用户在触摸屏和鼠标操作之间切换的操作。

Google Earth 的 UI 在最终用户与不同的外围设备交互时,在典型的桌面和移动可视提示之间切换

结论

使用Flutter重新构建Google Earth带来的最大的意外收获,来自平板电脑和网页等中间环境的使用者。这些设备夹在手机和平板电脑之间,可以在物理上支持两种类型的体验,但很少享有与之匹配的软件灵活性。同样地,网页体验可以在任何设备上加载;在桌面电脑上,浏览器可以任意调整大小。根据应用程序的不同,所有这些都可能意味着截然不同的UI。对于大多数将每个构建目标的代码库分开的开发团队来说,完全支持身处这些中间状态的使用者是不可能的。(想象一下说服你的老板花时间在行动装置上重建你的整个桌面UI,仅仅因为平板电脑使用者想要它!)

但是,正如Google Earth团队所发现的,虽然在一个代码库中构建完全適應性的 UI确实意味着額外的複雜性,但它被满足所有使用者需求所獲得的使用者體驗改進所抵消。

您今天就可以嘗試Google Earth的新Flutter實作,方法是在Android或iOS上下载應用程式,或访问 https://earth.google.com


Flutter極致UI適應性:Google Earth如何支援地球上所有用例 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

Flutter 和 Dart 套件生態系統的進展

Flutter 和 Dart 套件生態系統仍然是開發人員從單一程式碼庫為任何螢幕構建美麗、高效能應用程式的關鍵推動因素。該生態系統在 2023 年成長了 26%,從 1 月份的 38,000 個套件增加到 12 月份的 48,000 個。

Line chart depicting the growth in number of packages on pub.dev in 2023

截至 2024 年 1 月,Pub.dev 擁有超過 700,000 名月活躍使用者。Flutter 團隊仍然熱衷並致力於支持這種未來發展,並使開發人員能夠使用和貢獻 Flutter 和 Dart。在此更新中,我們將回顧最新的 Flutter Favorites、套件生態系統虛擬峰會的結果,並分享一些值得注意的更新和需要了解的事項。

新的 Flutter Favorites

Flutter Favorite logo

Flutter Favorites 程式表彰並幫助開發人員發現最高品質的套件,供他們在應用程式中考慮使用。我們很高興宣布七個新的 Flutter Favorite 套件,它們已證明了卓越的品質、人氣和社群參與度,使它們成為 Flutter 開發人員的無價工具。讓我們深入了解每個套件:

  1. flame:一個適用於 Flutter 的高性能 2D 遊戲引擎。其直觀的 API 和豐富的功能集使其成為構建視覺上令人驚嘆且引人入勝的遊戲的理想選擇。查看 這個 Codelab 以嘗試使用 flame 構建遊戲。
  2. flutter_animate:使用這個強大的動畫函式庫讓您的 UI 動起來,它可以簡化複雜的動畫,並使所有 Flutter 開發人員都能使用它。其宣告式語法和豐富的文檔使建立流暢且富表現力的動畫變得輕而易舉。
  3. riverpod:一個優雅的套件,提供一種功能強大且直觀的方法來管理應用程式狀態。其簡化的 API、性能、可擴展性和可測試性使其成為現代 Flutter 應用程式的引人注目的選擇。
  4. video_player:對於任何希望在其 Flutter 應用程式中整合影片播放的人來說,這都是必不可少的。它提供了一個 Widget 來顯示影片內容。它支援各種格式和來源,包括網路資源和基於檔案的影片。這使其成為構建富含多媒體的 Flutter 應用程式的多功能工具。
  5. macos_ui:對於以 macOS 為目標的開發人員來說,這個套件可以在該平台上創造出設計感覺恰如其分的應用程式。它提供了一套豐富的 Widget 和组件,這些 Widget 和组件的樣式符合 macOS 設計語言,確保您的 Flutter 應用程式不僅在 macOS 上運行良好,而且看起來和感覺都像原生應用程式。
  6. fpdart:這個套件在 Dart 中啟用函數式編程。它非常適合實現商業邏輯,例如,在函數式編程範式(如不可變性、純函數和高階函數)以及 fpdart 對 Dart 類型系統的使用方面,它有助於構建更易於維護和可預測的程式碼。
  7. flutter_rust_bridge:對於希望在應用程式中利用 Rust 和 Flutter 最佳功能的開發人員來說,flutter_rust_bridge 在兩個世界之間提供了一個無縫的橋樑。它使原生 Rust 程式碼能夠與 Flutter 無縫交互,解鎖 Rust 性能和記憶體安全性在 Flutter 應用程式中的潛力。

終止 Happy Paths 程式

我們決定終止 Happy Paths 程式,以便專注於 Flutter Favorites。Happy Paths 建議的願景是幫助您做出明智的決定,以便找到和使用套件來為您的應用程式添加功能。我們很幸運有像 Flutter Gems 這樣的社群倡議,它們是導航分類良好的套件選項的綜合資源。隨著我們專注於 Flutter Favorites 程式,我們將繼續在 Flutter 和 Dart 社群的意見和回饋的基礎上對其進行改進。

套件生態系統虛擬峰會

The Flutter and Dart Ecosystem Virtual Summit 2023 landing page

在 2023 年 8 月底,我們為 Flutter 和 Dart 套件生態系統舉辦了首次 虛擬峰會,超過 50 位非 Google 和 Google 貢獻者參加了 pub.dev。我們最初的邀請名單相對較小,以適合 unconference-style 的格式,並在弄清楚未來可能呈現的樣子之前,從這次首次活動中學習。目的是將貢獻者聚集在一起,進行 unconference-style 的討論,以便在社群中進行規劃、教育、學習和分享。我們進行了三個討論會,每個討論的主題都是由註冊參加者在峰會開始前的幾週中投票決定的。三個討論主題是:1)構建高品質套件——最佳實踐和挑戰,2)長期維護套件——可持續模式,以及 3)Flutter 和 Dart DevTools 擴展。對活動後調查的回覆為我們提供了寶貴的回饋,我們將在未來的活動規劃中將這些回饋納入其中。謝謝您!總體而言,我們認為這次首次峰會取得了成功。展望未來,我們渴望與社群合作舉辦類似的獨立活動,或者將焦點放在 Flutter 和 Dart 生態系統上的議程,並將其設定在更通用的活動中。

對 Pigeon 套件的更新

Pigeon 套件 是一個程式碼生成工具,它簡化了 Flutter 應用程式與平台特定程式碼之間通信的設定過程。這使得 Pigeon 在以下兩種情況下都很有用:1)在直接撰寫 Flutter 應用程式與平台原生 API 之間的自定義整合時,例如在 add-to-app 情況下,以及 2)在撰寫 Flutter Plugin 以為平台原生 API 提供 Dart API 表面時。它由 Flutter 團隊維護,該團隊在今年對該套件進行了以下值得注意的改進:

  • 加入對 Swift、Kotlin 和 C++ 的支援(C++ 解鎖 Windows 支援)。
  • 現在強制執行空安全。
  • 擴展對原始數據類型支持的支持。例如,枚舉被加入為支援的類型。
  • 加入可空參數。
  • 在主機和 Flutter API 上加入錯誤處理。
  • 改進了工具的人體工程學,使其更易於使用和更直觀。例如,我們加入了對預設參數和命名參數的支持。

在 1 月份的 v5.0.0 和 12 月份的 v15.0.2 之間,還有很多我們無法在此處列出的開發工作,因此請查看 變更日誌 中的所有變更!

DartPad 中的套件

DartPad 支援一組固定的套件,您可以透過點擊螢幕右下角的資訊圖示來查看這些套件。Google 的 Flutter 和 Dart 團隊會持續審查和優先處理套件請求。如果您希望將套件加入到 DartPad,請為 現有套件建議 點擊赞成(如果有),或者 開啟一個新的議題 提出您的建議。

Screenshot of packages on Dartpad.dev

建議在 pub.dev 上使用規範主題

在 2023 年,我們推出了讓套件作者能夠在 pubspec 檔案中使用 1-5 個自由文本主題為其套件加標籤的功能。目標是透過加入一種套件分類方式來改善潛在使用者發現套件的體驗。我們看到這個功能取得了良好的效果,許多套件都進行了標籤化。我們正在探討一個提案,透過合併實際上相同的主题來改進這個功能(例如,widget 和 widgets)。我們邀請社群對此 規範主题議題 分享回饋或貢獻 PR。

An example of Topics on a package on pub.dev

目前就這些了!若要與優秀的套件作者社群互動,請查看 Discord 頻道 #package-authors(您首先需要加入 Flutter Discord 伺服器)。


Flutter 套件生態系統的進展 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

構建史詩級的 Flutter 遊戲,協助保衛地球

我們知道 Flutter 開發人員喜歡挑戰,因此,適逢新年到來之際,我們很興奮地宣布下一場 Flutter 挑戰!

全球玩家挑戰 是一場為期 8 週的比賽,由 Flutter 和 Global Citizen 贊助,旨在設計、構建和發佈可持續的遊戲。比賽的獲獎者將獲得在 2024 年 9 月前往紐約市的機會,與 Flutter 團隊會面,進行一天的研討會和指導,然後在 2024 年的 Global Citizen Festival 上與多達 60,000 位其他 Global Citizen 共同慶祝他們的成就。

什麼是可持續的遊戲?

可持續的遊戲利用遊戲的力量來激勵積極的環境行動。想像一下 Candy Crush,但不是粉碎糖果,而是粉碎塑膠污染!或者,想像一下像 Super Dash 這樣的遊戲,但不是收集橡子,而是你在 Dash 的家中想辦法透過優化使用窗戶而不是空調的氣流路徑來降溫。以下是一些受目前正在執行的 Global Citizen 活動啟發的更多想法:

  1. 鼓勵減少家庭能源使用

    資料顯示,美國家庭的平均用電量是全球其他典型家庭的三倍。您可以構建一個遊戲來幫助減少對低效率能源的依賴嗎?

  2. 鼓勵減少使用一次性塑膠

    東南亞的塑膠污染水平居世界之首。考慮構建一個遊戲來鼓勵人們進行替換,例如選擇可重複使用的水瓶而不是一次性水瓶。

  3. 鼓勵在短距離內使用公共運輸工具,在長距離內使用陸路運輸

    歐洲擁有世界上許多最好的公共運輸系統。有效的遊戲可以鼓勵人們在短距離內使用當地公共運輸,以及長距離內使用陸路運輸(例如火車而不是飛機)。

我們相信遊戲可以鼓勵玩家採取一些小的、真實的行動,這些行動加起來對環境產生巨大的影響。事實上,如果您想直接採取行動,請查看 Global Citizen 目前正在執行的活動

為什麼要加入全球玩家挑戰?

保衛地球

此比賽的靈感來自 Playing for the Planet 聯盟,這是一個由聯合國促成的 50 個遊戲工作室和公司的聯盟,包括 Google,其使命是減少該行業的環境影響,並利用遊戲的力量來提高人們對氣候變化、生物多樣性喪失和污染等重要環境問題的認識,並協調行動。

Playing for the Planet 聯盟成員製作的遊戲總觸達人數超過 10 億人。透過聯盟的旗艦計畫 Green Game Jam,參與的遊戲已透過籌款來種植 275 萬棵樹,並籌集了約 150 萬美元來保護野生動物和支持環境事業,創造了實際的影響。

我們已與 Playing for the Planet 聯盟合作,為環境遊戲來源 最佳實務,並將它們加入到此挑戰中提供的資源包中。這是您構建有助於保護地球的事物的機會!

學習新知識

無論您是 Flutter 開發人員,對遊戲很陌生,還是遊戲開發人員,對 Flutter 很陌生,或者您同時對遊戲開發和 Flutter 很陌生,在對世界產生積極影響的過程中,您一定會學到一些技巧。

詳細資訊

時間表

所有專案必須在 2024 年 3 月 5 日下午 2:59 PT (GMT -8) 之前提交。前 20 名將於 2024 年 3 月下旬公布,最終獲獎者將於 2024 年 5 月公布。

提交指南

註冊和提交條目說明可在 DevPost 找到。

獎項

獲勝者將根據以下標準進行評估:

  • 原創性和創造力
  • 可持續的行動和故事
  • 動畫的使用
  • 有效的多平台部署

雖然我們不僅會獎勵出色的程式設計能力,但是我們也會為好點子、演示影片、遊戲的教育內容以及更多內容提供獎勵!

資源

我們編譯了一系列 資源 來幫助您構建遊戲,其中包括一個 指南 來引導您完成此挑戰,就像遊戲地圖一樣。它會向您展示您需要的資源,幫助您透過 Global Citizen 應用程式中的 全新學習旅程 成為 Global Citizen,並包含有關如何註冊和提交遊戲的說明。

團隊

我們建議您以團隊的形式完成此挑戰。當您在 Devpost 上 註冊參加挑戰 時,您將能夠分享您的技能、團隊狀態和想法。

因此,無論您有很棒的想法,但需要技術技能的隊友來實現它,或者您擁有技術技能,但想要很棒的想法,請務必相應地填寫您的個人資料,然後瀏覽 參與者標籤,尋找個人資料詳細資訊與您尋找的內容相符的人!

我們對技術專家和活動家共同努力實現共同目標的想法特別感興趣。如果您需要額外的支援來尋找隊友,請閱讀這篇 幫助文章

最後,請注意,團隊可以是任何規模,但如果專案被選為決賽,每個團隊只有 3 人可以前往紐約市。

開始並保持連線

flutter.dev/global-gamers 的官方比賽網站上查看您需要了解的所有資訊。您也可以訪問 DevPost 進行註冊並提交您的遊戲。

提交截止日期為 3 月 5 日,所以不要猶豫!我們迫不及待想看看您將構建什麼!


宣布 #GlobalGamers 挑戰 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

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

如何打造:Ask Dash - 一款生成式 AI Flutter 應用程式

作為 [Google Cloud 應用 AI 峰會](https://cloudonair.withgoogle.com/events/summit-applied-ml-summit-23?talk=t1_s5_vertexaisearchandconversation) 的一部分,Flutter 和 Vertex AI 團隊與 [Very Good Ventures](https://verygood.ventures/) 合作,使用 Google Cloud 的 [Vertex AI Search and Conversation](https://cloud.google.com/vertex-ai-search-and-conversation) 打造出了一款 AI 驅動的 Flutter 範例應用程式 [Ask Dash](https://github.com/VeryGoodOpenSource/dash_ai_search)。 Vertex AI Search and Conversation 使您能夠快速構建和部署搜尋和對話式應用程式,幾乎不需要任何 AI 經驗。 Flutter 是構建美觀、自訂搜尋體驗的絕佳方式,可以展示這兩款產品如何在短短幾週內共同構建強大的應用程式!

Vertex AI Search and Conversation 讓您能夠建立與您的資料互動的應用程式,這些應用程式會提供個人化的回應,展示生成式 AI 的強大功能。最重要的是,它讓您完全控制您的應用程式存取和索引的資料,以便您可以控制向哪些使用者顯示哪些資訊。所有應用程式資料和使用者互動都儲存在您自己的雲端實例中,從未使用於訓練 Google 的基礎機器學習模型。

由於我們使用 Flutter 打造了範例應用程式,因此我們決定使用 Flutter 文件作為訓練資料。我們與 Google Cloud 團隊合作,針對 Flutter 和 Dart 開發人員文件特別訓練了模型,以便為以下類型的問題提供生成式 AI 回應:Flutter 是什麼?它支援哪些平台?熱重載是什麼?雖然這些資料中的大部分在公開的 AI 模型中很容易獲得,但此範例展現了如何僅根據您自己的資料訓練模型,以建立強大的 AI 體驗。

本文將帶領您瞭解我們的合作夥伴 Very Good Ventures 如何打造 Flutter 網頁應用程式,以及我們如何在雲端主控台中連接應用程式。

如何打造 Flutter 網頁應用程式

建立基於 Flutter 文件訓練的搜尋應用程式的想法很簡單。事實上,[Flutter 的官方文件](https://docs.flutter.dev/) 已經提供了簡單的搜尋體驗,可以為有關 Flutter 的問題提供相關的頁面結果。但是,在構思要建立什麼時,我們希望展示 Flutter 如何用於建立視覺上吸引人的互動式體驗,這些體驗有趣且引人入勝。

在 Flutter 中建立互動式動畫

Flutter 使團隊能夠無縫地實作各種動畫。它豐富的動畫集,加上 Widget 的靈活性,讓我們能夠建立轉場、引人入勝的動作效果和流暢的使用者互動。從在生成結果時建立動畫載入狀態,到在答案出現時揮手的 Dash 精靈,Flutter 提供了靈活性,可以將基本的文字回應變成使用者可以互動的有趣內容。

視覺化自然語言搜尋結果

與傳統的搜尋體驗不同,Vertex AI Search 會針對提問提供自然語言回應。答案是使用從 Flutter 文件中多個頁面擷取的 AI 生成的,並以摘要回應的形式呈現,以及顯示 AI 使用的相關頁面的卡片。每張卡片都提供了頁面的標題和描述,以便使用者可以翻閱卡片以更深入地了解 AI 回應。

此外,在自然語言回應中,Vertex AI Search 會提供一個連結,指向回應中每個句子的來源,讓使用者可以更深入地了解每個回應部分的來源。在範例中,點擊每個句子旁邊的數字就會翻轉卡片到相關的來源頁面。

在更短的時間內更引人入勝

在開始這個專案時,我們有一個很緊迫的時程表,要讓範例應用程式在 [Google Cloud 應用 AI 峰會](https://cloudonair.withgoogle.com/events/summit-applied-ml-summit-23?talk=t1_s5_vertexaisearchandconversation) 上發佈。Flutter 的高效開發和易於使用,大大加快了兩個開發人員團隊的開發過程。它提供了建立複雜動畫所需的工具和框架,使我們的團隊能夠在活動開始前的兩週內完成這個範例應用程式的打造和發佈。

將 Flutter 應用程式連接到 Vertex API

我們使用 [http 包](https://pub.dev/packages/http) 進行簡單的請求,將前端網頁應用程式與 Vertex AI Search API 整合。 Vertex AI Search 在無需任何預先建立 AI 經驗的情況下,會提供使用者生成的問答的 JSON 回應,這些回應會被解析並顯示在動畫 Widget 中。這讓團隊可以專注於 Flutter 開發,以從生成的資料中建立引人入勝的體驗。

在您的應用程式中設定生成式 AI 搜尋

設定 Vertex AI 並為我們的 Flutter 應用程式託管 API 也非常簡單。在我們的例子中,我們使用 [https://docs.flutter.dev/](https://docs.flutter.dev/) 作為我們的資料源,並直接在 Google Cloud 主控台中設定它。作為 Google Cloud 客戶,開始使用 Vertex AI 只需三個步驟:

  1. 建立資料儲存庫

這是您網站的數位資料庫,它儲存了您根據根 URL 生成 AI 模型所需的所有資訊。Google Cloud 會爬取您的網站以查找相關資料,並為您建立一個可以查詢的資料源。若要在 Google Cloud 主控台中設定此項目,請選取 **Search and Conversation**。選擇 **Data Stores**,然後選擇 **New Data Store**。選擇 **Website URL** 作為來源,並提供您網站的 URL。

2.存取您的資料

接下來,在 Cloud 主控台中建立一個應用程式,以導航模型索引的資料,並將其連結到您先前建立的資料儲存庫。在 **Search and Conversation** 下,選擇 **Apps**,然後選擇 **New App**。選擇 **Search** 作為類型,並為您的應用程式提供一個反映其用途的名稱,例如 Ask Dash。

3.製作一個 Cloud 函式

最後,建立一個 Cloud 函式。這是將 Vertex AI 資料公開給其他應用程式的 API 介面。在主控台中,前往 **Cloud Functions**,然後選擇 **Create Function**。

就是這樣!

從這裡,您可以像使用任何 API 一樣在前端應用程式中使用 API,傳送請求並接收應用程式可以顯示的格式化回應。若要測試它,請前往 **Function** 頁面,然後選擇 **Testing**。輸入一個 JSON 物件,其中包含用於提問的「search_term」金鑰(例如「hot reload」),然後查看包含自然語言摘要、相關引文和引用的頁面簡要摘要的詳細回應。

在 Google Cloud 的文件 中瞭解如何開始使用 [Vertex AI Search](https://cloud.google.com/generative-ai-app-builder/docs/try-enterprise-search)。

在 Flutter 中打造的生成式 AI 應用程式

若要查看 Ask Dash 的實際操作,並瞭解我們如何打造它,請查看 [Google Cloud 應用 AI 峰會](https://cloudonair.withgoogle.com/events/summit-applied-ml-summit-23?talk=t1_s5_vertexaisearchandconversation) 的影片議程,其中 Google Cloud 產品經理 Alan Blount 詳細介紹了打造過程,以展示 Vertex AI Search 在 Flutter 應用程式中的潛力。查看 [範例的開源 Flutter 程式碼](https://github.com/VeryGoodOpenSource/dash_ai_search),並開始在 Google Cloud 主控台中體驗自己的 AI 搜尋體驗。

Ask Dash 僅是一個開始,展示了 Flutter 如何在應用程式中為互動式生成式 AI 體驗提供動力。我們迫不及待地想看看你將打造什麼!


如何打造:Ask Dash - 一款生成式 AI Flutter 應用程式 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

了解我們如何用兩位開發人員在桌面瀏覽器、Android 和 iOS 上推出了 Super Dash,一款多平台遊戲範例

Super Dash 是一款使用 Endless Runner Flame Template 建立的新 Flutter 範例遊戲,它隨最近更新的 Flutter 休閒遊戲工具包 推出。

我們與 Google 的 Flutter 團隊合作,在短短六週內使用 Flutter 和 Flame 從想法到推出開發了一款適用於 Android、iOS 和 Web 的多平台遊戲。這款遊戲的靈感來自超級瑪利歐等懷舊經典,玩家可以在橫向捲軸平台遊戲中扮演 Dash,她會收集橡果和雞蛋以最大限度地提高分數,並逐級闖關。

這款遊戲可以在 桌面瀏覽器 上玩,並可在 Apple App StoreGoogle Play 上使用行動裝置玩。這款遊戲的程式碼(包括行動平台)是開源的,可在 GitHub 上的 super_dash 儲存庫中取得。

如何遊玩

Dash 會在每一關中收集橡果(10 分)和雞蛋(1000 分)以提高分數。按下空格鍵或點選螢幕即可開始遊戲,並跳躍避開蟲子和掉進坑洞,以完成每一關。抓住金羽毛即可將 Dash 變身為鳳凰,增加她的跳躍高度,並讓她獲得額外一條生命。

使用 Flutter 快速無縫地進行遊戲開發

Flutter 使我們能夠在短短六週內,僅憑我們團隊中的兩位開發人員,將想法變成實際的遊戲。這個框架能夠透過熱重載功能快速迭代變更,加上平台的可組合性、模組化和可用工具,讓團隊能夠快速行動,並與設計團隊的合作成果一起快速測試和開發遊戲。

它還加快了團隊針對行動裝置建立響應式 UI 的速度,同時也鎖定瀏覽器和桌面。這讓我們能夠將更多開發時間投入到遊戲本身,並減少花在確保遊戲在不同設備和螢幕上運作的時間。

此外,Flutter 和 Dart 強大的 套件生態系統 以及與 Firebase 等 Google 服務的整合,讓我們能夠輕鬆找到工具,例如 Flutter_Bloc,它使我們能夠無縫建立遊戲邏輯和狀態管理。

Flame 動力的 Flutter 冒險

Super Dash 使用 Flame,一個用 Flutter 建立的開源遊戲引擎。雖然許多休閒遊戲可以使用 Flutter 單獨建立,但 Flame 擴展了 Flutter 的遊戲開發功能,適用於需要遊戲迴圈、碰撞和地圖的遊戲。

Super Dash 利用 Leap 專案 擴展了在 休閒遊戲工具包 中可用的 Flame Template 的基本功能,這是一個由 Kurtome(Flame 社群成員)建立的開源專案。在使用 Leap 之前,您應該對 Flame 的 FlameGamePositionComponentTiledComponentCamera 組件有基本的了解。

在儲存庫中,您會找到我們為除錯遊戲而建立的自訂工具,包括帶有各種動作和工具的 macOS 版本。我們加入了一個「傳送至終點」按鈕,讓 Dash 無需玩完全程就能直接到達終點畫面,以及另一個讓 Dash 不死的按鈕,讓您可以在不重新啟動的情況下玩完全程。您可以在 super_dash 儲存庫 中找到這個工具,並在建立或擴展遊戲時親自嘗試。

所有物理物件都有矩形碰撞盒,由物件的大小和位置定義,它們不必與物件的視覺外觀相同,這大大提高了可玩性。

團隊使用 Firebase 分發 輕鬆共享應用程式和遊戲的測試版本,特別是 iOS,因為 iOS 有時會很複雜。

設計一個互動式的 Dash 世界

Super Dash 的設計非常直觀,易於玩。我們使用開源的 Tiled 工具設計關卡,並使用 leap 套件將關卡整合到遊戲中。

Leap 使用 flame_tiled 套件(其中實作了 TiledComponent),並在此基礎上建立,加入了平台物理和有用的類別,例如適用於物件、敵人和玩家的 PhysicalEntity。flame_tiled 套件解析來自 tiled 的檔案以渲染地圖、圖層和物件。

Background static image

LeapMap

一個透過 LeapGame.leapMap 可以存取的組件,LeapMap 管理 Tiledmap,並自動為地面地形建立具有適當碰撞偵測的方塊。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void main() {
runApp(GameWidget(game: MyLeapGame()));
}

class MyLeapGame extends LeapGame with HasTappables, HasKeyboardHandlerComponents {
late final Player player;

@override
Future<void> onLoad() async {
await super.onLoad();

// "map.tmx" should be a Tiled map the meets the Leap requirements defined below
await loadWorldAndMap('map.tmx', 16);
setFixedViewportInTiles(32, 16);

player = Player();
add(player);
camera.followComponent(player);
}
}

若要加入自訂行為,請透過 LeapGame.leapMap.tiledMap 存取圖層,並為方塊或物件整合您自己的特殊行為

自訂圖層名稱和類別

您可以要求 Leap 使用不同的類別、類型或名稱。若要這樣做,請建立並將自訂 LeapConfiguration 傳遞給遊戲。

以下範例建立了自訂 LeapConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MyLeapGame extends LeapGame {
MyLeapGame() : super(
configuration: LeapConfiguration(
tiled: const TiledOptions(
groundLayerName: 'Ground',
metadataLayerName: 'Metadata',
playerSpawnClass: 'PlayerSpawn',
hazardClass: 'Hazard',
damageProperty: 'Damage',
platformClass: 'Platform',
slopeType: 'Slope',
slopeRightTopProperty: 'RightTop',
slopeLeftTopProperty: 'LeftTop',
),
),
);
}

我們與 HOPR Studio 合作設計和製作遊戲的美術作品。為了建立更無縫的工作流程,我們建立了描述項目行為的通用語言。例如,一個「I」代表無限,表示項目會以相同的方式重複執行(從左到右或反之亦然)。這使得每個團隊更容易理解遊戲的目標。地圖準備好後,我們便將其整合到遊戲開發中。

Super Dash Game instructions

接下來的目標

Super Dash 範例在 2023 年 11 月更新的 Flutter 休閒遊戲工具包 之後發佈,並使用了 新的遊戲範例,展示了 Flame。透過強調我們在短短六週內就完成了從想法到推出,我們希望展示 Flutter 如何幫助您提高生產力,並在各種平台上接觸更多使用者。查看 開源程式碼 以了解我們是如何建立的。

現在可以在桌面瀏覽器上 玩遊戲,或在 Apple App StoreGoogle Play 上下載行動裝置應用程式!你能打破最高分記錄嗎?


我們如何在短短六週內使用 Flutter 和 Flame 建立 Super Dash 範例! 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

宣布 Dart 3.2

作者: Kevin MooreMichael Thomsen

今天,我們宣布推出 Dart 3.2,其中包含一個新的語言功能,用於對私有 final 欄位進行非空推斷,透過新的互操作性功能改進開發人員體驗,支援 DevTools 中的擴展,以及關於我們的 Web 路線圖的更新,包括對 Wasm(又名 WebAssembly)的支援。

私有 final 欄位的非空推斷

自從我們在 Dart 2.12 中引入 可靠的空安全 已經過了好幾年。在空安全中,您可以宣告哪些類型是可空的(可能包含值或 null),以及哪些類型是非空的(始終包含值)。空安全與 流分析 結合在一起,可以偵測到可空變數何時可以「推斷」為更安全的非空類型:

1
2
3
4
5
6
7
8
int definitelyInt(int? aNullableInt) {
if (aNullableInt == null) {
return 0;
}
// 如果流分析到達此處,
// aNullableInt 可以安全地推斷為非空的 int。
return aNullableInt;
}

類型推斷自 Dart 2.12 起一直是空安全的核心部分,但僅限於區域變數。欄位或頂層變數無法推斷,例如在這種情況下:

1
2
3
4
5
6
7
8
9
class Container {
final int? _fillLevel;
Container(this._fillLevel);
check() {
if (_fillLevel != null) {
int i = _fillLevel; // 在 Dart 3.2 之前,會導致錯誤。
}
}
}

這種限制是由于在流分析無法安全地確定何時或如何更改欄位的一些複雜情況造成的。例如,在類別的欄位推斷情況下,如果子類別使用 getter 覆蓋欄位,而 getter 有時會返回 null,就會出現問題。

在 Dart 3.2 中,我們改進了我們的流分析引擎,現在能夠推斷 私有 final 欄位 的類型。現在,上面的程式碼片段可以在沒有錯誤的情況下通過。這利用了這樣一種了解,即對於私有和 final 欄位,在初始賦值之後,該值永遠不會改變,因此只檢查一次被認為是安全的。私有的 final 欄位推斷從 Dart 3.2 開始可用,並且將應用於 Dart SDK 下限 為 3.2 或更高的專案。

package:lints 3.0 中的新的程式碼分析選項

說到程式碼分析,我們還在 package:lints 中對我們的標準程式碼分析規則進行了一些改進。這個套件包含與使用 dart createflutter create 建立的任何新專案一起提供的預設和推薦的靜態分析規則集(透過 package:flutter_lints - package:lints 的擴展)。

這個 lint 集的最新主要版本 3.0 現在已經可以使用了。此修訂版在核心集添加了六個 lint,在推薦集添加了兩個 lint。它具有用於驗證 pubspec URL、驗證集合方法是否使用正確參數調用等的 lint。若要查看完整的更改列表,請查看 變更日誌。3.0 版本將是下一個版本中新專案的預設版本。對於現有專案,您可以 立即升級

Dart 互操作性更新

各種平台 上的多平台支援一直是 Dart 的核心原則。但是,即使 Dart 程式碼行可以在所有這些平台上無需更改地執行,大型應用程式仍然經常需要與現有程式碼互操作。這可能意味著來自舊專案的程式碼,或在其他函式庫或系統 API 中可用的 API。我們在這個領域進行了一系列投資,從用於 與原生 C API 互操作 的 FFI 開始。我們目前正在努力將其擴展以支援與 Java 和 Kotlin 以及 Objective C 和 Swift 互操作。有關 JS 互操作性的令人興奮的更新,請查看下面的 Dart Web 部分。

截至 Dart 3.2,我們對原生互操作性進行了許多改進:

  • 我們為 C FFI 引入了 NativeCallable.isolateLocal 建構函式,它從任意 Dart 函數建立 C 函數指標。這是 Pointer.fromFunction 提供的功能的擴展,它只能從頂層函數建立函數指標。
  • 我們更新了 Objective-C 綁定生成器,以使用 NativeCallable.listener,我們在 Dart 3.1 中添加了它。生成器現在可以自動處理包含異步回調的 API,例如 Core Motion。以前,此類 API 需要手動編寫一些綁定程式碼。
  • 我們繼續改進用於 Java 和 Kotlin 互操作性的 package:jnigen。這使我們能夠將 package:cronet_http - Android Cronet HTTP 客戶端的包裝器 - 從手動編寫的綁定程式碼遷移到自動 生成的 包裝器。
  • 我們在 原生資產 功能方面取得了重大進展,該功能旨在解決與依賴原生程式碼的 Dart 套件分發相關的許多問題。它透過提供用於整合與構建 Flutter 和獨立 Dart 應用程式相關的各種構建系統的統一掛鉤來實現。若要查看預覽,請查看 文件

Dart 套件的 DevTools 擴展

Dart DevTools 是一套用於除錯和效能分析的工具,支援純 Dart 和 Flutter 應用程式。在 Dart 3.2 和 Flutter 3.16 中,我們 宣布 推出一個新的 擴展框架,它使套件作者能夠為他們的套件構建自訂工具,並直接在 DevTools 中顯示。這允許包含框架的 pub.dev 套件提供專門針對其用例的自訂工具。例如,Serverpod 的作者一直在努力為他們的套件構建開發人員工具,並且很高兴地宣布他們将在即将发布的 1.2 版本 中发布 DevTools 扩展。

計劃在即將推出的 ServerPod 1.2 版本中使用的 DevTools 擴展

Dart Web 和 Wasm 更新

Wasm(也稱為 WebAssembly)是一種用於 Web 瀏覽器的令人興奮的新指令格式,它提供了一種可移植、平台中立的二進制程式碼格式,以便在現代瀏覽器中執行。像 Dart 這樣的更高級別的受控語言使用垃圾收集,而垃圾收集正在添加到 Wasm 標準中。截至 Chrome 119,Wasm 的垃圾收集支援(稱為 Wasm-GC)已預設啟用。Wasm-GC 支援也即將在 Firefox 120 中推出,這是他們的下一個穩定版本。那麼 Dart、Flutter 和 Wasm-GC 的狀態如何呢?

Dart 到 Wasm 編譯器幾乎已完成功能。團隊對效能和相容性非常滿意。我們現在的重點是邊緣情況,以確保我們的輸出在各種情況下都能快速執行。

對於 Flutter Web,我們已完成一個新的「Skwasm」渲染引擎。為了最大限度地提高效能,Swasm 將編譯後的應用程式程式碼直接連接到使用 wasm 到 wasm 綁定的自訂 CanvasKit Wasm 模組。它也是 Flutter Web 多線程渲染支援的第一個版本,它可以進一步提高幀時間。

在 Flutter Web 與 Wasm 擺脫目前的實驗狀態之前,還有一些事情需要完成:

  • 雙重編譯: 生成 Wasm 和 JavaScript 輸出,并在運行時啟用功能偵測,以支持具有 Wasm-GC 支援和沒有 Wasm-GC 支援的瀏覽器。
  • 現代 JavaScript 互操作性: 基於 擴展類型 的新的 JS 互操作性機制,以在針對 JavaScript 和 Wasm 時,在 Dart 程式碼、瀏覽器 API 和 JS 函式庫之間實現簡潔、類型安全的調用。
  • 具有 Wasm 支援的瀏覽器 API: 一個新的 package:web,基於現代 JS 互操作性機制,取代 dart:html(以及相關的函式庫)。這將為 JS 和 Wasm 目標上的瀏覽器 API 提供簡單的存取權。

我們開始將許多內部專案遷移到 package:web 和新的 JS 互操作性機制,並預計在下一個穩定版本中會有更多更新。同時,您可以在我們的 WebAssembly 支援 頁面上獲取最新詳細資訊。

結語

今天就到這裡。Dart 3.2 現在可以從 dart.dev 中獲取,或者作為今天 Flutter 3.16 版本的一部分。下次再見,祝您使用 Dart 開發愉快!


宣布 Dart 3.2 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

undefined