【文章翻譯】We’ve moved! The official Dart blog has a new home

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

1
2
3
4
5
6
7
8
9
10
11
#### 官方 Dart 部落格已遷移至 [**dart.dev/blog**](https://dart.dev/blog)!

<figure>
<img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cZZyASylK6dJfEEn8t9Dmw.png" />
</figure>

歡迎來到我們的新家!官方 Dart 部落格已從 Medium 遷移到 [**dart.dev/blog**](https://dart.dev/blog)。未來,您將在此處找到所有語言發佈公告、深入技術文章以及來自 Dart 團隊的工程更新。

更新您的書籤並加入我們吧!

<img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2b9ea40d2a72" width="1" height="1" alt=""><hr><p><a href="https://medium.com/dartlang/weve-moved-the-official-dart-blog-has-a-new-home-2b9ea40d2a72">我們搬家了!官方 Dart 部落格有了新家</a> 最初發佈於 <a href="https://medium.com/dartlang">Dart</a> 的 Medium 上,人們在那裡透過突出顯示和回應這個故事來繼續對話。</p>

【文章翻譯】Learning faster with Antigravity

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

Dash 享受反重力

為 ADK 建立 Flutter 前端

當代理程式使用我從未用過的 SDK 和語言構建時,我該如何為它建立 Flutter 前端?

這是我在處理使用 Agent Development Kit (ADK) 編寫的基於 Python 的代理程式時面臨的挑戰。由於 Python 經驗有限,且以前從未接觸過 ADK 框架,因此構建一個與後端伺服器整合的客戶端帶來了巨大的學習曲線。此外,即使我能讓程式碼代理程式產生一些可行的東西,如果我不理解程式碼,完成專案也是一種失敗的形式。

然而,在幾次失敗的嘗試之後,我找到了答案。我與我的 AI 編碼夥伴 Antigravity 採用了結構化、迭代的工作流程,建立了一個可重複使用的開發人員技能,將我在每次循環中學到的知識編碼化。我從零開始,產生了關於程式碼的筆記,建立了多個連接到 deep_search 代理程式(來自官方 ADK 範例儲存庫的多代理研究協調器)的應用程式,並逐步建立了技能和我的理解。有時,我同時使用了多個代理程式,「作者」代理程式與我一起建立技能,「編碼員」代理程式使用該指南來建立前端。

我最終得到的是一個名為 flutter_frontend_for_adk 的代理程式技能。它包含五個參考文件,引導 Antigravity 經歷一系列階段,每個階段都以可交付成果結束。第一階段產生了以下筆記文件,以便我可以結構化「編碼員」代理程式在分析代理程式並準備產生應用程式時對任務的思考:

  • AGENT_INTERFACE_NOTES.md — 在分析代理程式原始碼時所做的筆記。它的目的是什麼,它是如何構建的?這個代理程式公開了哪些介面和 API,它們是如何運作的?
  • FRONTEND_USAGE_NOTES.md — 第一個規範。前端應該做什麼,使用者應該如何與它互動?
  • FRONTEND_ARCHITECTURE_NOTES.md — 架構計畫。應該建立哪些服務、類別、狀態和模型?
  • FRONTEND_DESIGN_NOTES.md — 前端的設計文件。它會是什麼樣子?顏色、字體和其他細節是什麼?

之後,Antigravity 可以產生應用程式的程式碼,運行並測試它。雖然技能(和我)仍在開發中,但我現在已經很好地掌握了 ADK,並且有了一種有用的方法來為現有代理程式建立前端。

這就是它的發生方式。

deep_search 代理程式生成前端的截圖

從他人的工作開始

我不是這裡唯一一個編寫技能的人,所以第一步是從 Google Cloud 和 Flutter 團隊安裝一些技能:

1
2
npx skills add google/agents-cli --skill google-agents-cli-adk-code
npx skills add flutter/skills

這讓我對 ADK 及其 CLI 工具和 Flutter 有了一些基本的了解。由於 Antigravity 的 Dart 擴充功能,我也安裝了 Dart MCP 伺服器。

建立循環

我沒有一開始就要求代理程式產生一個應用程式,而是與它建立了一種「學習循環」。首先,我要求編碼代理程式執行我技能中的工作流程,然後我與作者代理程式合作手動評估編碼程式的輸出,找出技能說明中的漏洞,並更新指南以改進未來的運行。每次迭代後,我會刪除產生的筆記和應用程式,重新開始,然後發現我需要學習的下一件事。

看我的迴圈!

該循環由與 Antigravity 對話驅動的五個不同步驟組成:

1) 執行目前的技能:在一次新的對話中,編碼代理程式執行由目前版本的技能檔案定義的工作流程。

我的提示:這個程式碼庫包含一個使用 ADK 構建的代理程式,但沒有前端或客戶端。我希望您閱讀 flutter-frontend-for-adk/SKILL.md 中的說明並遵循工作流程。不要檢查 git 歷史記錄,不要參考我們進行過的任何其他對話的上下文,也不要更改 git 分支。

2) 評估輸出和規範:在第二次對話中,作者代理程式和我檢查產生的可交付成果,例如架構筆記、設計規範和產生的程式碼結構。我更擅長發現結構問題,而 Antigravity 則幫助我捕捉所有小細節。

我的提示:在我審查筆記和程式碼時,請查看生成的工件並告訴我您認為它們與說明和我們的目標的匹配程度。

3) 識別差距和故障模式:我們識別出程式碼代理程式缺乏特定指導、做出不正確假設或遇到整合問題的領域。

我的提示:我在上次運行中發現了兩個問題:首先,根 gitignore 由於全域的「lib/」忽略規則而忽略了新的 frontend/lib/ 資料夾。其次,程式碼代理程式連續執行所有六個階段而不停止。我們需要一種方法來在每個階段之後暫停並驗證可交付成果。

4) 更新核心技能和參考資料:我們更新 SKILL.md 中的說明或 references/ 目錄中的子指南以解決這些差距。

我的提示:讓我們更新 SKILL.md 中的 Phase 6,明確處理 gitignore 問題,方法是如果「lib/」全域忽略,則添加「!frontend/lib」。此外,在 Phase 1 到 4 的末尾添加一個強制性的「審查」步驟,指示代理程式暫停並等待我的批准,然後再繼續。

5) 清除本地文件並重新執行:我刪除臨時規範文件,重置 git 工作樹,然後回到循環的頂部。

儘管與一對代理程式合作確實加快了速度,但它並沒有使過程瞬間完成。我一次只能吸收這麼多資訊!但在每次迭代中,我都會閱讀筆記和原始碼檔案,查看與 Antigravity 的對話,並且(一旦我產生了真實的程式碼)運行應用程式以查看其效能。

一開始,我主要在閱讀和學習。但到最後,我對正在發生的事情了解得足夠多,足以專注於一直失敗的事情,開始自己研究,並調整程式碼以修復問題。修改完筆記和程式碼庫後,我會詢問 Antigravity 如何更新技能,以使未來的程式碼產生看起來更像我組裝的內容。因此,該技能不僅僅是程式碼代理程式的指令,更是我學習的記錄。

循環迴圈

總共經過 13 次迭代,我才得到一些我不羞於分享的東西。以下是前 6 次,主要用於發現和記錄筆記:

  1. 啟動和工作區映射 — 我意識到一個單一的、整體式的 SKILL.md 文件對於代理程式來說太難導航了。我將技能重構為模組化,建立了一個專用的 references/ 資料夾並編寫了第一個專業指南:references/agent_discovery.md。這讓 Antigravity 通過分析代理程式的原始碼並建立 AGENT_INTERFACE_NOTES.md 來記錄它學到的東西。
  2. 定義行為和使用者體驗 — 接下來是前端的使用規範:它會做什麼?使用者將如何與它互動?我在技能中添加了一個新階段,指示它閱讀 references/frontend_usage.md 並採訪我以了解平台偏好和功能要求。這讓我在觸摸程式碼之前就得到了 FRONTEND_USAGE_NOTES.md,它定義了應用程式的目的和功能集。
  3. 設定結構藍圖 — 架構。我們將 references/frontend_architecture.md 添加到技能中,該技能側重於前端所需的架構細節,我讓代理程式產生 FRONTEND_ARCHITECTURE_NOTES.md
  4. 設計視覺美學 — 我們建立 references/frontend_design.md 來指導代理程式如何定義視覺美學,並將 scaffolding 指令添加到 SKILL.md 中。此指南指示代理程式採訪我以了解主題、斷點和動畫偏好,Antigravity 開始產生 FRONTEND_DESIGN_NOTES.md
  5. 產生並運行應用程式 — 至此,我能夠告訴 Antigravity 開始根據我們收集的所有規範產生實際的 Flutter 程式碼。應用程式以驚人的方式失敗了,我意識到需要某種通用的「最佳實踐」文件來解決可能重新出現的問題。我們將 references/frontend_best_practices.md 添加到技能檔案中以指導實際的編碼,並開始一次修復一個問題。

從那時起,我繼續與 Antigravity 進行迭代,一次解決一個問題,更新程式碼,更新技能以匹配,然後清除產生的前端以再次嘗試。在此過程中,循環變得更緊密,更改更小。我做了七次額外迭代:

  1. 應用程式無法進行網路呼叫! — 修正了 macOS 和 iOS 的權限和資訊。
  2. 所有這些 Markdown 都沒有被格式化! — 利用 flutter_markdown 正確顯示來自代理程式的文字,其中通常包含 Markdown。
  3. 為什麼程式碼看起來不對勁? — 添加了 lint、格式化規則和其他產生後檢查。
  4. 密封類別! — 不同的訊息類型應共用一個基類型,以便應用程式可以使用窮舉 switch 語句。
  5. 為什麼聊天不會捲動? — 添加了 ScrollController,以便在新訊息到達時自動推進訊息列表。
  6. 為什麼應用程式在網路上運行時崩潰了? — 移除了 dart:io,轉而依賴 package:http 進行網路連線。
  7. 清單中的部分事件! — ADK 發送事件流,有時是分段的。前端需要將它們連貫地組裝和呈現,而不是向使用者顯示所有部分(帶有損壞的 Markdown 格式)的列表。
  8. 為什麼工具視窗是空白的? — 在產生時,應用程式沒有正確處理工具命名約定,並且事件處理沒有正確識別何時調用工具。

一個「出錯」的例子

為了讓您了解每次迭代中完成的工作,讓我們來看看其中一個變更:前端如何處理部分事件。

ADK 伺服器會串流事件,這些事件表示一小段內容或部分工具執行階段。但是,如果客戶端應用程式將每個傳入的網路事件都渲染為聊天清單中的獨立訊息氣泡,那麼介面就會變得碎片化。代理程式的一個回應將顯示為數十個孤立的、損壞的文字塊。

舊方法(一個簡單的清單):

1
2
3
4
5
6
7
8
// 在清單視圖中渲染每個原始事件區塊
ListView.builder(
itemCount: rawEvents.length,
itemBuilder: (context, index) {
// 每個部分文字區塊都在單獨的氣泡中渲染
return ChatBubble(text: rawEvents[index].contentText);
},
)

此程式碼導致的 UI 如下所示:

看看所有這些損壞的清單項目和半粗體的段落!

一旦你知道該怎麼做,這個問題的解決方法其實並不難。當然,我不知道,所以我開始向 Antigravity 提出問題,例如「ADK 如何使用 SSE 串流事件?」和「事件的傳輸資料結構是什麼樣的,我怎麼知道它是否是部分事件?」如果「氛圍學習」是真實存在的,我正在這麼做。

事實證明,您只需要檢查一個旗標,所以我調整了前端 AgentProvider 類別中的程式碼,要求 Antigravity 審查它以防我忘記了任何顯而易見的東西,然後運行應用程式進行驗證。我再次向 Antigravity 發出請求,以更新最佳實踐,以便每個新的前端都會使用這種方法。

新方法 (AgentProvider 中的聚合):

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
await for (final event in stream) {
if (event.partial && event.contentText != null) {
// 累積串流文字
_activeStreamingAuthor = event.author;
_activeStreamingResponse =
(_activeStreamingResponse ?? '') + event.contentText!;
} else {
// 完成的區塊:清除累加器並加入永久事件清單
_activeStreamingResponse = null;

final updatedEvents = List<Event>.from(_activeSession!.events)
..add(event);

// 合併狀態差量
Map<String, dynamic> mergedState = _extractSessionStateMap(
_activeSession!,
);
if (event.actions.stateDelta.isNotEmpty) {
mergedState.addAll(event.actions.stateDelta);
}

// 使用更新的事件和狀態建立 Session 的新副本
_activeSession = Session.fromJson({
'id': _activeSession!.id,
'app_name': _activeSession!.appName,
'user_id': _activeSession!.userId,
'events': updatedEvents.map((ev) => _serializeEvent(ev)).toList(),
'state': mergedState,
});

_processCompletedEvent(event);
}

notifyListeners();
}

親自試試看

我非常喜歡「做中學」,而嘗試完全超出我舒適區的東西(例如一種新語言和一個新 SDK)相當令人生畏。然而,擁有這個循環為我提供了一個可以參考的結構,這非常有幫助,現在我擁有了一個 漂亮的新代理程式技能

如果您還沒有,請自己下載 Antigravity 並試用一下 — 我只花了幾個小時,而且我確實學到了一些新技巧。

要開始:

  1. 下載 Antigravity 以將代理程式編碼助手整合到您的開發環境中。
  2. 訪問 AGY 入門 文件,了解如何定義自己的自訂開發人員技能和參考指南。
  3. 為您想要探索的框架草擬一個簡單的技能,並不斷循環直到您得到喜歡的東西!


使用 Antigravity 更快學習 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章翻譯】Vibe once, run anywhere with Antigravity and Flutter

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

與 Rody Davis 共同撰寫

程式碼代理程式及其使用方式在短短幾個月內就已經發生了巨大的演變。最初,重點主要放在觀察上——逐行審查每個輸出。但隨著模型能力迅速提升,業界轉向了真正的代理工程。如今,開發人員、PM 和設計師身兼多職,專注於崇高的概念目標,讓代理程式處理各個組件。

為了探索這個新領域,我們的團隊希望建立一個能展示這種確切工作流程的體驗。我們想建立一個遊戲,產生其資產,編寫行銷頁面,並部署整個項目,所有這些都使用 Google 首屈一指的 AI 原生平台:Antigravity。

Antigravity 將 Google 的最佳功能匯集於一處,採用規劃、執行和驗證的緊密回饋迴圈。它會建立 Artifact、撰寫程式碼、執行測試,甚至點擊 UI 中的按鈕,以確保它實際正確完成了任務。

我們代理程式冒險的成果是 DashLander——一款設定在程序生成的小行星上的月球著陸器風格遊戲。以下是我們如何建立它的故事。

在 AI 時代為何選擇 Flutter?

很多人可能會想:如果代理程式可以撰寫原生程式碼,為什麼不讓它們完全分開撰寫 Android、iOS 和 Web 應用程式呢?

這是一個合理的問題;這也是最初激發 Flutter 作為「Vibe once, run anywhere」UI 工具包概念的原因。

擁有單一真實來源對 AI 和人類都同樣重要。透過讓代理程式編寫單一的跨平台應用程式,團隊可以消除不同語言或平台特定範式之間不可避免地出現的細微錯誤。此外,Dart 強型別為 LLM 提供了出色的回饋。具有較鬆散型別系統的語言要求 LLM 進行更多的分析,才能知道給定程式碼在所有情況下是否正確。另一方面,Flutter 和 Dart 使用其分析伺服器向您的代理程式發送有關函數簽名或類別形狀不匹配的強烈訊號。搭配有狀態熱重載,Flutter 對代理程式的加速作用與對人類開發人員的加速作用一樣。

而且,儘管代理程式開發大幅降低了生產新軟體的成本,但它仍遠非免費。對於代理程式開發來說,時間就是金錢,這既是比喻意義上的,也是字面意義上的,因為查詢時間越長,意味著更多的令牌;這意味著更多的 AI 開支。有了 Flutter,成功完成編碼任務的代理程式無需重新開始支援另一個平台,從而為您節省了資金

快速失敗,才能建造更好

我們知道我們想建造一個遊戲,您在其中駕駛月球著陸器,配備動態元素、自訂著色器和粒子效果。(我們不忍心將 Dash 本身置於冰冷的真空空間,所以,您將駕駛一艘船。) 當然,使用 AI 大大加速了這些概念的整合,但這並不妨礙稍後放慢速度並認真編寫高品質程式碼。如果有的話,透過 AI 進行的快速探索階段有助於您更快地達到該階段,因為您的許多失敗實驗可以在幾個提示的生命週期內來去,而不是花費數小時或數天的編程時間,只是為了了解某個特定的想法是否真的很有趣。如果這輩子有一件事無關緊要,那就是從未見天日的實驗性功能的程式碼品質。

最重要的是,我們也知道我們沒有在建造什麼:一款高性能、即時的多人遊戲。即時多人遊戲功能會引入延遲限制並呈指數級擴大基礎設施複雜性。相反,我們意識到可以透過在挑戰模式中重播過去高分的回影來提供 90% 的引人入勝的競爭體驗。這使我們可以依賴靜態儲存和簡單的後端,並巧妙地免費重複使用完美編寫的「AI 對手邏輯」,只需重播最佳使用者已經做過的事情即可。這就是所有程式碼中最好的:您既不編寫也不維護的程式碼。

生成一個資產的宇宙

為了讓小行星著陸器遊戲變得有趣,我們需要出色的資產,我們在很大程度上依賴代理生態系統來獲取它們:

  • **音訊:** 我們使用 Google 的 Lyria 生成背景音樂。(不過,Rody 戴上他老音訊工程師的帽子,確實用麥克風、水管和噴霧罐在他家後院錄製了自訂的推進器噪音。多麼有趣的下午!)
  • **視覺效果:** 我們在 Stitch 和 Google Canvas 中生成了 UI 設計。Gemini 直接在程式碼中編寫了我們的粒子效果,我們使用 Nano Banana 生成了應用程式圖示。
  • **物理:** 因為這個遊戲發生在真空環境中,我們想要精確的反應控制系統 (RCS)。我們釋放了 Gemini Deep Research 來尋找我們需要的精確零大氣物理公式,它將這些公式編譯成 Google Doc。然後我們將該研究納入我們的語境中,Gemini 將方程式直接翻譯成 Dart。這些真的是正確的物理方程式嗎?可笑的是,我們不知道,因為我們不是物理學家!但是當您玩遊戲時,控制感肯定感覺正確。

**疊代原型**

我們從 AI Studio 的沙盒開始建立,以在提交架構之前生成快速、一次性的程式碼。這些豐富的原型可以作為模型以後的上下文壓縮,及早鎖定微觀決策。我們的一些原型具有更有趣的遊戲玩法,有些看起來更具吸引力,還有一些最清晰地捕捉了我們的零重力物理。對於我們的最終遊戲,我們將每個原型中最好的想法融合在一起。

一旦我們將專案載入 Antigravity,我們就為我們的代理程式配備了 Firebase、Flutter、Flame 遊戲引擎和 Gemini API 的 MCP 伺服器。我們啟動了一個新的提示,Antigravity 將任務分配給後端、UI 和遊戲邏輯的專門子代理程式。在五分鐘內,我們就有了一個用 Flutter 和 Flame 編寫的遊戲,這個遊戲通常需要幾天才能編寫。但實際上,它遠未完成。只有三個硬編碼的關卡,攝影機沒有跟隨著陸器,而且數學意味著我們的飛船大約有帝國大廈那麼大。

大約又用了 100 個提示才讓遊戲達到最終狀態。其中很大一部分提示只是關於程式碼組織和增加測試。每個人對閱讀 AI 生成的程式碼都有自己的看法,但 Rody 和我非常重視我所稱的「認知所有權」,並且仍然想了解我們應用程式的深層內部運作方式。我們閱讀了 Gemini 編寫的許多內容,並推動 LLM 進行重構以提高清晰度和可重用性。

我還必須面對一個嚴酷的現實:我不太擅長三角函數,而 DashLander 中確實有很多三角函數。當代理程式告訴我他們完美地實現了一個新的系統,例如著陸計算和得分時,我經常玩遊戲並立即發現差異。不幸的是,無論我在我的程式碼庫中閱讀 Gemini 密集的三角函數多少次,我都無法找出斷開點隱藏在哪裡。為了擺脫這個惡性循環,我要求 Gemini 在鍵盤快捷鍵後面建立一個絕密調試模式。它呈現了疊加層,顯示了確切的地形資料、表面的相對傾斜度和碰撞碰撞框,讓我能夠向自己證明代理程式的計算在哪裡是錯誤的。掌握了確鑿的證據,我能夠與 Gemini 合作解決了密集數學文件中的問題。

**時空旅行的棘手問題**

當我們加入挑戰模式時,Antigravity 在連接資料模型並將它們連接到 Cloud Firestore 方面做得非常出色。但在測試過程中,我發現了一個隱蔽的錯誤。我會與之前高分的鬼魂比賽,視覺上一切看起來都很棒,因為鬼魂飛船順利地漂移。但隨著重播的進行,事實證明鬼魂飛船與過去的自己不知不覺地脫節了。在比賽結束時,儘管原始玩家完美著陸,但鬼魂飛船有時會劇烈撞上小行星。

為了解決這個問題,我必須像 2023 年一樣,開動我的大腦。可怕,我知道。

我意識到核心問題是現代電腦架構的一個基本面向。您看,在現代多處理器 CPU 上,您可以告訴程式在未來精確的毫秒運行一段程式碼,但由於行程排程的性質,CPU 永遠無法保證完美精確度。而且,對我來說不幸的是,在重播期間啟動推進器的一毫秒延遲會從根本上改變飛船的模擬飛行路徑。我意識到,我不能僅僅記錄推進器時間戳,而是必須在每個推進器事件的精確時刻儲存著陸器物理狀態的完整表示,以校正重播期間的不準確性。Gemini 隨後整合了邏輯,以不斷將重播的即時模擬與這些物理檢查點進行比較,自動校正任何微小偏差。結果是完美無瑕、無崩潰的重播。

**從遊戲到發布**

您可能已經感受到在日常工作中身兼多職的壓力,無論您的團隊規模大小。例如,您可能擅長編寫遊戲,但不想推廣它們。或者,您是一位傑出的使用者體驗工程師,但更喜歡不處理圖形設計。好消息是,您不必獨自完成所有事情。

我們使用 Stitch 從單一提示生成了我們的行銷登陸頁面,並將我們正在運行的遊戲截圖作為上下文傳入。(誠然,如果生成優化的登陸頁面是我們的實際目標,我們會對此進行更多疊代。)使用一鍵匯出到 Antigravity,我們隨後下載了 HTML 並開始工作。因為我們是用 Dart 構建的,所以我們希望保持堆疊統一。我們使用 [Jaspr](https://pub.dev/packages/jaspr)(一個將 HTML 直接映射到 Dart 組件的 Web 框架)來無縫整合生成的 HTML。Gemini 完美處理了這種轉換,使我們能夠在遊戲和行銷網站之間共用程式碼,同時保留行業標準的 SEO 索引。

最後,我們使用 Antigravity CLI 來建構我們的 Flutter 網頁應用程式,將建構目錄複製到 Jaspr,執行建構腳本,然後直接部署到 Firebase Hosting——所有這些都在一個不間斷的終端工作流程中完成。

雖然 DashLander 目前以網路優先,以便輕鬆驗證機制,但由於它使用 Flutter 建構,我們只需一個指令即可部署到 iOS、Android、macOS、Windows、Linux,甚至豐田 RAV4 的資訊娛樂面板。截至撰寫本文時,該遊戲目前可在 [dashlander.com](http://dashlander.com) 上玩;但如果您在足夠遙遠的未來發現這篇文章,且該連結已失效,歡迎您直接從 [GitHub](https://github.com/craiglabenz/dashlander) 下載程式碼。

**實現您的願景**

若要開始建構您夢想中的應用程式或遊戲,請前往 [antigravity.google](https://antigravity.google) 獲取 Google 的 Agent Manager 和 IDE;並前往 [flutter.dev](https://flutter.dev) 開始使用 Flutter SDK。

祝您好運,我們迫不及待地想看看您會建立什麼!


使用 Antigravity 和 Flutter 實現一次設計,隨處運行 最初發佈於 Flutter 的 Medium 平台,讀者可在該平台透過高亮和回應此故事來繼續參與討論。

【文章翻譯】How we built a Flutter-powered AI coffee shop

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

Dash 坐在咖啡店的收銀檯上喝著拿鐵,上面印有 Flutter 標誌

如果你開始贈送咖啡,人們就會出現。Flutter 團隊曾嘗試過一段時間,想辦法將這個原則應用到一個從 Flutter 應用程式開始,以一杯熱騰騰美味飲料結束的演示中。問題是如何讓它更有趣、更個人化,而不僅僅是點餐和送餐。咖啡很酷,但它不像「你絕對會記得 Google I/O 的一件事」那麼酷。

那麼,什麼改變了呢?兩種新技術出現了。一個是 Nano Banana,它能夠快速生成客製化圖片。第二個是 GenUI,它能夠在執行時動態生成使用者介面,並為參與者提供個人化問題,詢問他們希望如何修改這些圖片。將這兩者與 Flutter 結合起來,你就可以讓大家有機會點一杯咖啡,上面印著他們快樂地方的圖片,使用噴墨印表機列印出來。那才真是令人難忘。

我們所要做的就是執行。事實證明是兩次——這個演示在 Cloud Next 上被稱為「GenLatte」,在 Google I/O 上被稱為「Antigravity Coffee Co.」。為了簡單起見,並為為您總結這篇文章的代理人節省一些標記,下面將使用「GenLatte」這個名稱。

我們開了一家咖啡店

實現 GenLatte 這樣雄心勃勃的願景需要很多人。真的,是很多人。有團隊來規劃實體空間並決定「顧客」[1] 將如何流動。有品牌和概念團隊來創造美學。當然,還有施工團隊去五金店購買木材。最終,還有軟體工程師將程式碼組合在一起以構建各種應用程式,這就是我碰巧參與的地方。這篇部落格文章只會概述軟體部分,但這並不是要淡化 GenLatte 最終開門所需的許多其他層面所付出的令人難以置信的工作。

[1] 如果不收費,他們還是顧客嗎?

GenLatte 的運作方式

GenLatte 的核心是一個 Flutter 應用程式,帶有 Firebase 後端。

再深入一步,它是一個 monorepo,包含獨立的 Flutter、Firebase 和共用程式碼專案。使用 monorepo 讓我們能夠重複使用依賴項,共用業務邏輯,並執行原子部署。Flutter 應用程式也運行在 iOS 和 Android 上,但客戶只與網頁版本互動。我們使用 Cloud Build 和 Firebase Hosting 來保持我們的部署故事,而不是「某人在他們的筆記型電腦上運行 $firebase deploy」。在伺服器上,我們混合使用了觸發函數和 HTTP 可呼叫函數,賦予應用程式在明確的資料流和反應式資料管理之間靈活性。

在 Flutter 應用程式本身中,我們構建了 5 個獨立的使用者介面:瞌睡的會議參與者點咖啡的 kiosk 螢幕、顯示新訂單的咖啡師螢幕、驗證每個提交內容安全性的協調者螢幕、一個大型隊列螢幕,讓客戶大致了解何時會收到他們的飲料,以及一個純粹異想天開的「近期訂單」螢幕,顯示最後 13 個訂單作為浮動氣泡,讓每個人都有最後一次機會欣賞他們的數位創作。

演示級別的安全性

Google 在任何涉及使用者生成內容的演示中,最主要的一個顧慮是防止志願者「慷慨捐贈」他們的紅隊專業知識,發布不適當的內容供公眾消費。實際上,這體現在幾個不同的方面:

  • 防止授權使用者建立 NSFW 內容: 為了防止這種情況,GenLatte 實施了三層方法。首先,原始的「快樂地點」字串被發送到 Gemini Flash 進行快速審核,並附帶大約三十個範例,概述我們希望阻止的令人不快的內容。然後,一旦「快樂地點」獲得批准,我們就開始生成圖片,並依靠 Nano Banana 自己的內部訓練來只生成 SFW 內容。在流程結束時,我們的人工審核員會手動批准每張圖片。有了這一切,我們非常有信心 GenLatte 不會讓 Google 難堪。
  • 防止管理員帳戶遭到冒用: 授權使用者可能破壞您應用程式的另一種方式是訪問您不打算共享的授予提升權限的螢幕。鑑於 GenLatte 的後台審核員和咖啡師螢幕,它顯然存在這種風險。我們選擇部署到網頁,使用者可以使用瀏覽器網址欄任意導航,這進一步增加了壓力。為了解決這個問題,我們的 GoRouter 實作具有集中式的宣告式路由檢查,以確保每次頁面訪問對於給定的帳戶都是合法的,這由 Firebase 自定義聲明決定。
  • 防止未經授權寫入 Firestore: 授權使用者使用應用程式是一回事,但有人閱讀 firebase_options.dart 的內容,啟動一個新專案,並查看他們能造成什麼破壞,則是另一回事。為了解決這個問題,我們將所有讀取和寫入都綁定到具有嚴格安全規則的嚴格帳戶憑證,您可以將其作為您自己專案的靈感

傳遞有趣的圖片

一旦我們確信我們的應用程式在演示現場不會被駭客入侵,我們就開始確保 Gemini 可以提供一致的圖片,這些圖片在咖啡上看起來很棒。這個專案部分可能涉及到在辦公室裡過度咖啡因化的下午,所以我們飛快地完成了它也就不足為奇了。

核心是,我們的系統涉及將使用者的「快樂地點」(一個字元上限為 50 個,但通常只有一兩個字詞的提示)提升為四個獨特且高度特定的圖像請求。例如,對於輸入「和家人在家」作為快樂地點的使用者,GenLatte 可能會向 Nano Banana 請求一張「樹林裡古樸的家,壁爐裡有火,餐桌上準備好晚餐。家裡滿是家人和朋友,大家都在慶祝和享受彼此的陪伴。燈光和氛圍是…」(依此類推)的圖像。Gemini 負責這個提升過程,這意味著四個提示都不同;提供了使用者在應用程式中看到的各種圖像。

我們也針對令人愉悅的構圖優化了 Nano Banana;特別是「主體呈現領先的 S 形曲線」,它在道路、河流、山丘、海岸線或其他抽象之間輪流。這個提示技巧大大提高了 Nano Banana 吸引人、可用的圖像的百分比。

A circular image of a husky walking down a winding path through the woods. The image is Sepia-toned and has blurry rings along the outside that are suggestive of espresso and milk foam.
範例 Nano Banana 圖片:小狗在小徑上。
A large compass sits atop a hill with winding paths. The image is sepia-toned and dark, blurry rings along the outside are suggestive of espresso and milk foam.
Nano Banana 圖片範例:山丘上的羅盤。
A smiling moon looks down on a landscape of trees and rolling hills. The image is sepia-toned and dark, blurry rings along the outside are suggestive of espresso and milk foam.
Nano Banana 圖片範例:異想天開的森林。

為了 GenLatte 的第二次亮相,也就是今年五月在山景城 I/O 的 Antigravity Coffee Co.,我們更新了我們的提示,使其可以在不同的建議構圖之間輪流。這讓每天看到數百張圖片的活動工作人員和只想要為他們咖啡提供引人入勝的圖片的個別客人都能保持新鮮感。

即時修改圖片

GenLatte 的真正魔力不僅來自於快速製作圖片並將其列印在咖啡上;而是來自於根據個人確切的口味進行精確調整。在「調整」按鈕後面有四個問題,由 Gemini 預先撰寫,用於說明圖片可能如何修改。

這些圖片源自於原始的、升級後的提示本身;因此回到我們之前舒適的家庭快樂之地,Gemini 可能會提供關於餐桌上食物種類、人數多寡,或者慶祝活動是否是為了任何特定人生事件的問題。使用者看到的「和家人在家」的其他快樂之地可能會走向不同的方向,因此調整這些選擇會浮現出適合這些圖片的不同問題。

一旦使用者回答完問題,我們就帶著相同的提示回到 Nano Banana,同時提交多次以獲得新的藝術作品。提示看起來像這樣:

1
2
3
4
5
6
7
8
9
10
11
12
在看到來自此原始提示的圖片後:

{{original_prompt}}

使用者要求這些更改:

{{questions[0].body}}: {{questions[0].answer}}
{{questions[1].body}}: {{questions[1].answer}}
{{questions[2].body}}: {{questions[2].answer}}
{{questions[3].body}}: {{questions[3].answer}}

請生成此新圖片。

從拉斯維加斯到山景城,經過數月打造 GenLatte 後,看到人們因修改後的圖片而臉上發光,對我們來說是多麼神奇!

A2UI 和 GenLatte

GenLatte 不僅僅是 Flutter 和 Firebase 演示,甚至不是生成式 AI 演示;它是一個 GenUI 演示。GenUI 可以以許多不同的形式出現,但對於 GenLatte 而言,它連接了向使用者顯示正確的使用者介面以回答 Gemini 問題之間的點。關鍵細節是並非所有問題都最適合相同的 UI。像「您的家人正在慶祝特定的人生事件嗎?」這樣一個開放式問題需要一個文字欄位;但「現在是一天的什麼時候?」可能只有幾個相關選項,因此最適合單選按鈕。

在應用程式中實作 GenUI 有多種方式。保守的一端是嚴格控制、按部就班的體驗,代理程式從粗粒度 widget 目錄中選擇以渲染可預測的 UI。更具冒險精神的應用程式可以給予代理程式更多自由,從更細粒度的目錄中組合 UI,以渲染幾乎任何可以想像的東西。對於 GenLatte,我們選擇了保守的一端:公開一個小的品牌化 widget 目錄,代理程式可以使用它來顯示問題。這讓 Gemini 能夠在當下選擇正確的 widget,同時確保整體構圖符合我們的設計準則。

如果您想了解 Gemini 如何在更大的自由度下發揮作用,請查看 Hatcha,這是一個派對規劃應用程式。它透過將更多的執行時職責委派給 Gemini,進一步深入 GenUI。

三千杯咖啡之後…

在 Google Cloud Next 上供應了 1,200 杯拿鐵,在 Google I/O 上又供應了 1,800 杯,可以肯定地說 GenLatte 取得了成功。在建立這個演示或在這兩個活動中工作期間,我很少像現在這樣咖啡因過量,我也從未見過人們在使用應用程式後立即露出如此愉悅的笑容。

Flutter 讓異想天開的使用者介面建置過程充滿樂趣;從它對動態佈局和自訂著色器的優雅支援,到它無縫地針對多個平台的能力。Firebase 讓後端變得輕而易舉:為我們處理部署和擴展的麻煩,並提供反應式、全棧資料綁定。Gemini 和 Nano Banana(當然)將我們使用者的快樂地點提示變成了奇幻的藝術,看到它實體化令人愉悅。當然,操作真正的英雄是我們的咖啡師,他們製作了出色的拿鐵——因為如果咖啡不好喝,整個活動都會失敗!

若要閱讀 GenLatte 的程式碼,請訪問其在 flutter/demos 儲存庫中的資料夾。但是請注意,該儲存庫中的程式碼未經維護,僅供參考。

我們對 2026 年的應用程式開發未來感到興奮。有了 Flutter、Firebase 和 Gemini 等工具,您可以實際提供給使用者的體驗範圍呈指數級增長。

若要開始使用 GenUI,請訪問 Flutter 的文件。如果您對如何在自己的工作中運用這些模式有任何想法,請告訴我們,在此之前——我們迫不及待想看到您的創作!


我們如何建立一間由 Flutter 驅動的 AI 咖啡店 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章翻譯】Flutter Q2 survey

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

Dash 完成了第二季 Flutter 調查!

再次提醒!請參加 Flutter 第二季調查!調查將於 6 月 19 日星期五當天結束。

這不會花費您太多時間,您的回饋將有助於推動我們的發展藍圖!

謝謝您!


Flutter 第二季調查 最初發佈於 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章翻譯】That’s a wrap: Everything Flutter at Google I/O 2026

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

好的,以下是您提供的文章的繁體中文 Markdown 輸出:

總結:Google I/O 2026 Flutter 精華總覽

Flutter recap at Google I/O 2026!

多麼精彩的一週!Google I/O 2026 正式落幕。是時候回顧 Flutter 和 Dart 社群的旋風式更新了。

現場的明星是一個位於 Google I/O 絕對中心的、完整大小的特色咖啡店,它完全使用 Flutter GenUI 建造,其中奈米香蕉生成的藝術品直接印在咖啡泡沫上。

Just a few generated foam coffee art lattes at I/O

但是,如果您未能前往 Shoreline,請不用擔心。我們記錄了每一個時刻,甚至更多,現在可以在 Flutter YouTube 頻道上隨選觀看。

📺 觀看所有議程

從主題演講到技術議程,我們迫不及待地想讓您看到 I/O 2026 上 Flutter 的每一個時刻。

🌟 Flutter 新功能

其中一些亮點:

  • Flutter 3.44 和 Dart 3.12: 這些版本帶來了重大進展,包括智能熱重載 (Agentic Hot Reload)、GenUI (由 DeepMind 團隊的 Li-Te Cheng 展示),Toyota 已將 Flutter 嵌入 2026 年的 RAV4 中,Impeller 改進了渲染效能,Material 和 Cupertino UI 與框架解耦,Swift Package Manager 預設在 iOS 和 macOS 上啟用,Canonical 現在主導 Flutter 桌面路線圖,以及 HCPP 對平台特定保真度的重大更新。

🌟 感受一次,隨處運行:Antigravity 與 Flutter

  • 您將學到: 技術性地介紹 Antigravity,一個專注於使用代理構建的新 IDE。您將學習如何利用「基於氛圍」的開發來創建能夠無縫適應並運行於所有平台的體驗。
  • 為什麼它很重要: 它提供了從「硬編碼」佈局轉變為「基於氛圍」的生成體驗的架構路線圖,讓您的應用程式能夠即時適應使用者需求。

如何寫出真正好的 Flutter 程式碼

  • 您將學到: 撰寫高品質、可維護的 Flutter 程式碼的原則,以及現代工具——包括 Widget 預覽、DevTools、MCP 伺服器和技能——如何讓建構出色的應用程式變得前所未有的容易。
  • 為什麼它很重要: AI 可以比以往任何時候都更快地撰寫程式碼,但最佳實踐和強大的工具提供了長期維護 Flutter 應用程式所需的品質控制。

推出全端開發者系列

  • 您將學到: 不多,但這個不到兩分鐘的影片很有趣,並介紹了這個四集系列。

全端開發系列 #1 — Flutter + A2UI = GenUI

  • 您將學到: 深入了解生成式 UI 的建構區塊,以及如何將基於文字的聊天機器人從上到下轉換為一個能夠創建自己的 UI 並理解您與之互動方式的代理。
  • 為什麼它很重要: GenUI 不僅可以將緩慢的基於文字的體驗轉變為令人愉悅的體驗,它還開闢了新的使用者體驗模式,其中靜態設計和路由層次結構變成了針對個人使用者及其目標量身定制的靈活、按需 UI。

全端開發系列 #2 — 全端 Dart

  • 您將學到: 如何透過將 Dart 用於前端和後端邏輯來統一應用程式的技術棧並消除上下文切換。本影片使用 Dart for Firebase Cloud Functions 即時建構一個完整的無伺服器應用程式。
  • 為什麼它很重要: 這種方法透過讓團隊在整個應用程式棧中共享邏輯、工具和專業知識,從而提高了開發速度並降低了成本。

全端開發系列 #3 — 推出 Genkit Dart

  • 您將學到: 如何建立為您的應用程式後端和前端提供動力的 Genkit 流程,並探索保護您的 AI 端點所需的基本安全步驟。本影片涵蓋了從初始設定到實施速率限制和快取的所有內容,以確保您的專案安全且具有成本效益。
  • 為什麼它很重要: Genkit 彌合了原型設計和交付可靠 AI 應用程式之間的差距。它透過提供跨多種語言和模型的一致 SDK,以及強大的除錯和監控工具,簡化了將 AI 整合到現有程式碼中。Genkit 不僅作為後端運行,還可以在您的 Flutter 應用程式中運行!

全端開發系列 #4 — 您不知道的關於使用 Flutter 建構出色原生應用程式的一切

  • 您將學到: 我們為 Flutter 做出所有微小的改進,以提供引人入勝的原生體驗,從採用原生工作流程,支援 Dart 綁定生成的新語言,到平衡主機 UI 和 Flutter 需求的新渲染方法。
  • 為什麼它很重要: Flutter 並非為了尋找「最低公分母」。它旨在提供一個高保真度、高效能的框架,該框架尊重並增強其運行的原生平台。

…就是這樣!

感謝大家與我們一起參與這場我們最喜歡的 I/O 盛會之一。請繼續關注更多關於我們宣布的所有內容的部落格文章、影片和文件,以及我們從下個月開始將參加的 所有社群活動

Farewell from Google I/O 2026!

總結:Google I/O 2026 Flutter 精華總覽 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章翻譯】What’s new in Flutter 3.44

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

Flutter 3.44: 在更多裝置上擴展至更多使用者!

在 Google I/O 2026 賦予開發者能力

Flutter 3.44 登場,這是一個重大版本!此版本慶祝 Flutter 時間軸上的一個里程碑:Android 上的 Hybrid Composition++、Swift Package Manager 成為新的 iOS/macOS 預設值,以及 Impeller 對 Vulkan 的改進支援。我們正在預覽多視窗桌面支援,Canonical 將成為我們新的主要維護者,並透過將 Material 和 Cupertino 從核心框架解耦,開啟一項重要的架構演進。我們正在透過 GenUl 重新定義代理使用者體驗的 UX,並透過 Agentic Hot Reload 和 Dart & Flutter Agent Skills 重新構想開發者體驗。Flutter 正在賦予新一代應用程式無處不在的能力,從 2026 年 Toyota RAV4 多媒體系統到即將推出的 LG webOS SDK。我們非常興奮能與您分享所有新聞和更新;歡迎來到 Flutter 3.44!

Flutter 無處不在,日復一日,由每個人建造,為每個人服務。

今年 Google I/O 上 Flutter 的主題是:Flutter 無處不在,日復一日,由每個人建造,為每個人服務。

「無處不在,日復一日」源於我週二在使用手機上的應用程式時的一個發現:Flutter 應用程式無處不在我的生活中,從在灣區追蹤我的餐點到在日本購物。數字也支持這一點:pub.dev 生態系統比以往任何時候都更受歡迎,僅在過去 30 天內,套件下載量就超過 13 億次。Flutter 現在是兩個主要應用程式商店中 第二受歡迎的行動開發 SDK,每月開發者超過 150 萬,僅一年就增長了 50%。

「由每個人建造,為每個人服務」反映了我與 Google I/O 共同主持人 Kate Lovett 關於我們全球社群喜悅的對話。我們 1,700 多名忠誠熱情的貢獻者 是這項進步背後的引擎,在過去一年中,他們在核心儲存庫中完成了 5,800 次變更。僅在此發佈週期中,我們就完成了來自 178 位獨特貢獻者972 次提交,其中包括 61 位新貢獻者 完成了他們的第一批提交。我們的社群仍然是 Flutter 的命脈,確保它真正由每個人建造,為每個人服務。謝謝!

有很多變化要告訴您。您可能還想查看 Dart 3.12 版本中的變化

開發者體驗

無論您是手動撰寫程式碼還是使用您喜歡的程式碼代理進行疊代,我們都希望讓使用 Flutter 建立應用程式的體驗盡可能高效。在此版本中,我們正在改進我們現有的開發者工具套件並引入新工具來增強您的開發工作流程。

DevTools 效能改進

我們正在引入細粒度分析以提高效率,並且我們針對包含許多檔案或目錄的專案的分析進行了效能改進。

我們還為 Flutter DevTools 增加了更多的穩定性和效能改進,包括預設使用 WASM 的變更,這使得 DevTools 更快、回應更靈敏。

了解更多:DevTools 2.55.02.57.0 的發佈說明。

Widget 預覽 (實驗性)

此版本為 Widget 預覽環境帶來了進一步的效能改進和功能:

  • 預覽偵測重寫:偵測邏輯現在利用 Dart Analysis Server,顯著減少了 flutter 工具的記憶體使用量。對於 IDE 使用者,整體記憶體使用量應減少高達 50%。
  • 預覽篩選:現在可以按群組、名稱以及腳本和套件 URI 篩選預覽,使在具有許多預覽的專案中工作變得更容易。特別感謝社群成員 NamanGoyalK貢獻
Widget 預覽使您能夠單獨預覽獨立 Widget,與您的完整應用程式分開

了解更多Flutter Widget Previewer

無 Rosetta 的原生 Apple Silicon 支援

運行 Apple Silicon 晶片的 Mac 開發人員不再需要安裝 Rosetta 轉譯層來運行 Flutter。所有 macOS 命令列工具,包括我們的 iOS 裝置通訊二進位檔,都已更新為在 ARM 上原生運行。此更新早於 Apple 計畫棄用 Rosetta 轉譯支援,確保您的開發環境在 Apple 硬體上是未來的。展望未來,Flutter 的未來版本將完全終止對 Intel x86 Mac 的支援。如果您的團隊仍然依賴基於 Intel 的 Mac 主機進行開發,您應該開始規劃您的硬體遷移。

了解更多在配備 Apple 晶片的 Mac 上使用基於 Intel 的應用程式 (support.apple.com)

在 AI 驅動的世界中重新構想開發者體驗

在過去的一年裡,Dart 和 Flutter 生態系統見證了 Antigravity、Gemini CLI、Claude Code 和 Cursor 等基於代理的工具的爆炸式增長,這些工具正在從根本上將開發者的角色演變為與代理進行架構和協調的角色。為了支持這種轉變,我們專注於增強我們的開發者體驗基礎並引入新工具來增強您的開發工作流程。

與 Agentic Hot Reload 無縫整合程式碼代理

在 AI 輔助開發方面邁出了一大步,我們正在推出 Agentic Hot Reload:MCP 伺服器和您喜歡的程式碼代理現在將自動查找並連接到正在運行的 Dart 和 Flutter 應用程式。這意味著 Antigravity 等程式碼代理現在可以立即熱重新載入您正在運行的應用程式!當您提示您的 AI 助理編輯 UI 時,代理會編寫程式碼並自動觸發熱重新載入以立即向您顯示結果,無需手動設定。去試試看吧!我們還……

  • 強化依賴搜尋:代理現在可以安全地讀取和搜尋套件依賴項中的檔案,而無需完全存取您的本地 pub 快取。
  • 整合工具:我們整合了我們的 MCP 工具定義,顯著降低了您的代理工作流程的 Token 成本。

查看 Agentic Hot Reload 的實際應用:

Agentic Hot Reload:您可以提示您的代理進行更改,它現在會自動連接到並熱重新載入您正在運行的應用程式

我們最近還推出了 Dart 和 Flutter 的 Agent Skills,為您的程式碼代理配備了面向任務的生產級領域專業知識。這些技能提升了您的程式碼代理,並在完成諸如添加整合測試或設定本地化等任務時幫助您節省 Token,同時遵守推薦的最佳實踐。

了解更多Introducing skills for Dart and FlutterDart and Flutter MCP server

Dart & Flutter Agent Skills 為您的代理提供逐步說明,說明如何完成各種任務,例如撰寫整合測試

Flutter 讓 AI 遍布每個螢幕:建立下一代 AI 原生應用程式

隨著 AI 驅動的功能從簡單的內容摘要演變為完全代理式的助理,我們專注於擴展 Dart 和 Flutter 生態系統,以在每個平台上提供這些體驗所需的基礎設施。

Firebase AI Logic

Firebase AI Logic 使您能夠從您的 Flutter 應用程式中呼叫 Gemini API 客戶端。

MacroFactor 是一個 Flutter 應用程式,它使用 Firebase AI Logic 直接連接到 Gemini 模型並利用其多模態功能。我一直在用它來追蹤我的餐點,只需拍照即可。這是一個應用程式的絕佳範例,它使用 AI 將繁瑣的雜務變成令人愉悅、看似神奇的使用者體驗。

Firebase AI Logic 現在提供 伺服器提示範本,無需直接將提示嵌入到您的應用程式程式碼中。

適用於 Flutter 的 Firebase Agent Skills 現已推出,提供逐步指導,幫助您更有效地建立全端 Flutter 和 Firebase 應用程式。

MacroFactor 是一個 Flutter 應用程式,它使用 Firebase AI Logic 直接呼叫 Gemini 模型,利用其多模態視覺功能來簡化記錄餐點的使用者旅程。

了解更多: MacroFactor 利用 Firebase、Flutter 和 Gemini 革新 40 萬+ 使用者的營養

Genkit Dart 預覽

我們也很興奮地分享 Genkit Dart 的預覽發佈,這是一個用於構建全端、AI 驅動和代理式應用程式的開源框架。它具有模型不可知的 API,支援 Google、Anthropic 和 OpenAI 等提供商。它隨附了您從原型到生產所需的一切,包括類型安全的結構化輸出、工具呼叫、多輪對話和內建可觀測性。

您也可以在 Flutter 應用程式中運行 Genkit Dart 伺服器端或客戶端!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import 'package:genkit/genkit.dart';
import 'package:genkit_google_genai/genkit_google_genai.dart';

void main() async {
final ai = Genkit(plugins: [googleAI()]);

final response = await ai.generate(
model: googleAI.gemini('gemini-flash-latest'),
prompt: 'Why is Dart a great language for AI
applications?',
);

print(response.text);
}

了解更多Genkit Dart:使用 Dart 和 Flutter 建立全端 AI 應用程式

Gemma 3n 影響力挑戰賽

我們非常自豪地看到 Flutter 開發人員正在突破 AI 的可能性極限。恭喜 Gemma Vision 的創建者 Tommaso Giovannini 和 Vite Vere 的創建者 Guido Marangoni 在去年的 Gemma 3n 影響力挑戰賽 中分別獲得第一和第二名。兩者都選擇 Flutter 來建立改變生活的工具:

  • Gemma Vision 幫助視障人士感知世界
  • Vite Vere 協助認知障礙人士完成日常生活中的任務。
恭喜 Gemma Vision 的創建者 Tomasso 和 Vite Vere 的創建者 Guido。他們在 Gemma 3n 影響力挑戰賽中分別獲得第一和第二名!

了解更多Gemma 3n Impact Challenge 獲勝者

Gemma 4

Gemma 4 最近發佈,它是一個輕量級、設備上模型,專為高級推理和代理工作流程、成本、設備上資料限制或網路限制而設計。其多模態功能非常出色,我對它執行多階段規劃和鏈接工具呼叫的能力印象尤為深刻。

歷史上,在不同的硬體上管理這些設備上模型很複雜。這就是為什麼我對 LiteRT-LM 如此興奮的原因。

了解更多Gemma 4

LiteRT-LM for Flutter

當我深入研究 Gemma Vision 和 Vite Vere 的程式碼時,看到兩者都利用 flutter_gemma(一個可在 pub.dev 上取得的 Plugin)與 Gemma 整合,這真是令人鼓舞。

情況只會越來越好:我們很高興地宣布,針對 Flutter 的完整 LiteRT-LM 支援即將在 flutter_gemma 套件中推出。

LiteRT-LM 是 Google 的生產就緒、高效能、開源推理框架。這將抽象化硬體差異,讓您可以在裝置上運行 Gemma 4 等強大的設備端 AI 模型,同時確保在 Flutter 的所有 6 個穩定平台(Android、iOS、Web、Windows、Linux 和 macOS)上都能透過 GPU 和 NPU 加速實現最佳效能。

了解更多flutter_gemma 套件和 LiteRT-LM

Flutter + A2UI = GenUI

當談到 AI 驅動的使用者體驗時,我們都同意我們已經厭倦了 Markdown 文字牆——或者更糟的是純文字。

生成式 UI (GenUI) 是一種 UX 範式,AI 建立並回應即時 UI,而不是僅僅是文字,如 Hatcha Demo 應用程式所示。

Hatcha 是一個由 Flutter GenUI 提供支援的社交活動規劃應用程式。主持人透過對話式訪談進行規劃,而 GenUI 則根據您的活動及其受眾生成主題邀請、量身定制的組件和規劃模組。

在過去一年中,我們的 GenUI 團隊一直在作為專案合作夥伴推動這一進程,定義新興的 A2UI 協定。A2UI 是 Google 的開源協定,定義了代理和客戶端如何協作組合和狀態使用者介面。

自去年底推出 Flutter GenUI SDK 以來,我們看到了令人難以置信的發展勢頭,自年初以來,套件下載量增長了 500%。

一個突出的例子是 Catagay Ulusoy 的 Finnish it (Google Play 商店Apple 商店)。這個應用程式不僅建立自訂課程計畫來幫助使用者學習芬蘭語;它還會動態為每節課構成完美的 UI。如果您上個月觀看了 Cloud Next 開發者主題演講,您可能已經看到 Flutter DevRel 負責人 Emma Twersky 為該應用程式和 Catagay 做了應得的宣傳!

Flutter DevRel 負責人 Emma Twersky 在 Google Cloud Next 開發者主題演講中宣傳「Finnish It!」應用程式!

了解更多genui 套件

視覺佈局實驗

Google DeepMind 的李特·程和他的團隊是 GenUI 領域的先驅。還記得因為在 2023 年 Flutter 圈子中流傳的紅色調試橫幅而廣為人知的 這個 Demo 嗎?是的,那就是李特·程的團隊!

他加入了我們的 Flutter 最新功能演講,分享了他使用 Flutter 建立 Gemini 應用程式「視覺佈局」實驗的經驗。這是網頁版本:

從初始使用者提示開始,視覺佈局實驗鼓勵使用者透過生成式 UI 選擇、點擊和探索動態自訂和更新的資訊。

他談到了為什麼他的團隊傾向於選擇 Flutter 作為他們的首選 UI 工具包……提示:這就是我們都喜歡 Flutter 的原因:

  • 美麗的 UI
  • 高效的開發者體驗
  • 多平台支援
  • 一個完美適合 GenUI 的架構(李特·程的話,不是我的!😉)

以下是他的 3 個主要心得,您可以將其用於自己的 GenUI 專案:

  1. 依賴具有意見的框架來保持 AI 的一致性
  2. 使用「AI 評論家」循環以確保可靠的輸出
  3. 使用模板平衡速度和控制。

最後,李特·程挑戰我們超越文字牆和聊天機器人,而是建立豐富、互動、令人愉悅的體驗。

了解更多Flutter 的 GenUI SDK,如果您想要一個帶導向的教學,請 嘗試 Codelab

Android 支援

Googlebook 和周邊支援

Flutter 已具備處理由 Gemini 驅動的新 Googlebook 筆記型電腦的能力。由於 Flutter 針對 Android 的大螢幕指南,應用程式可以自然地處理外部硬體輸入。觸控板捲軸、滑鼠懸停狀態、右鍵選單和鍵盤快捷鍵預設都能運作。由於 Flutter 在 macOS、Windows 和 Linux 上都有成熟的桌面支援,因此 Flutter 應用程式在 Googlebook 上會感覺原生且反應靈敏,而不是看起來像拉伸的行動應用程式。現有的行動應用程式在 Googlebook 上會很舒適,無需大量重寫。

了解更多Introducing Googlebook, designed for Gemini intelligence

Android 17

Android 17 即將推出,團隊正在積極測試 Flutter 與最新的 Android 17 beta 版,以確保您的應用程式繼續按預期工作。我們還主動整合最新的安全性和可用性功能,例如本地網路保護和安全動態程式碼載入。

您可以在 GitHub 上監控我們正在進行的進度。我們鼓勵您 下載 Android 17 beta 版 並立即開始測試您的應用程式。如果您遇到錯誤或發現任何遺漏的功能,請 提交議題!

了解更多Android 17 GitHub 專案

Hybrid Composition++ for Android

將網頁視圖或地圖等原生 Android 組件嵌入到 Flutter 應用程式中,歷史上一直迫使開發人員在影格速率和保真度之間做出選擇。舊的渲染策略在捲軸時會出現畫面撕裂、文字輸入損壞或高 CPU 開銷等問題。

Flutter 3.44 引入了 Hybrid Composition++ (HCPP) 作為可選功能來解決這些問題。HCPP 不再依賴離線緩衝區或強制 Flutter 引擎處理原生視圖,而是將圖層合成直接委託給 Android OS。該過程利用 Vulkan 圖形函式庫的低階存取,使用硬體緩衝區交換鏈和 SurfaceControl 事務來同步 Flutter UI 與原生 Android 視圖。

結果是高效能的捲軸和精確的觸控輸入。它還為 SurfaceView 組件帶來了可靠的支援,這些組件在舊模式下曾帶來挑戰。

左側為 HC,右側為 HCPP

HCPP 有 Android API 和硬體要求,因此即使啟用 HCPP,也並非所有裝置都可以使用 HCPP。沒有新的 API 需要採用,您只需啟用該旗標即可升級現有的平台視圖。您可以透過將 --enable-hcpp 旗標傳遞給運行命令,或將設定旗標新增到 AndroidManifest.xml 檔案中,在未來成為預設渲染模式之前測試新模式:

1
2
3
<meta-data
android:name="io.flutter.embedding.android.EnableHcpp"
android:value="true" />

了解更多使用平台視圖在您的 Flutter 應用程式中託管原生 Android 視圖

Android 顯示器圓角半徑支援

為協助您在現代行動裝置上建立像素完美的佈局,Flutter 現已直接與 Android 硬體整合,以支援顯示器圓角半徑 (#179219)。Flutter 現在可以查詢裝置顯示器的物理和邏輯圓角半徑,並透過 MediaQuery 暴露此資訊。這使您的 UI 能夠準確地遵守硬體幾何,確保內容永不被積極圓角的螢幕剪裁。

了解更多MediaQueryData.displayCornerRadii

Android Gradle Plugin 9.0 和內建 Kotlin

在 Android Gradle plugin (AGP) 9 之前,Android 應用程式和 Plugin 開發人員必須手動將 Kotlin Gradle plugin (KGP) 添加到他們的建置檔案中,以便系統能夠理解和編譯 Kotlin 程式碼。從 AGP 9.0 開始,Android 建置系統原生處理 Kotlin。由於建置系統已經知道如何處理 Kotlin,手動添加單獨的 KGP 現在會產生衝突並導致建置失敗。此重大變更影響了套用 KGP 的應用程式和 Flutter Plugin。

Flutter 團隊添加了臨時向下兼容性,以確保現有專案安全建置。手動套用 KGP 的支援將在未來版本中移除。

應用程式開發人員說明

如果您開發 Flutter 應用程式,您需要更新您的 Android 建置檔案以移除單獨的 Kotlin Gradle Plugin (KGP)。

注意:如果您的遷移應用程式使用仍然套用 KGP 的 Flutter Plugin,您的建置將會失敗。由於只有 Plugin 作者可以修復此問題,請將 問題回報給 Plugin 作者

了解更多:有關完整的逐步說明,請參閱 應用程式開發人員遷移指南

Plugin 作者說明

Plugin 的遷移過程需要類似的 Gradle 檔案變更,以及重要的版本限制更新。為確保相容性,您必須更新 pubspec.yaml 檔案以 設定 Flutter 最低版本限制為 3.44

了解更多:有關完整檢查清單,請參閱 Plugin 作者遷移指南

ABI 篩選變更

ABI 決定了您的編譯應用程式支援哪些裝置硬體架構(例如 ARM 或 x86)。Flutter 過去以程式設計方式將 ABI 篩選器應用於每個特定的建置類型,但現在在基本 defaultConfig 區塊中配置一次。由於 AGP 9 將預設配置與特定建置類型和風味結合,而不是覆蓋它,因此使用自訂 ABI 設定需要額外的步驟。

如果您的應用程式在特定的建置類型或產品風味中使用了自訂 abiFilters,您現在需要在建置或運行應用程式時傳遞 -Pdisable-abi-filtering=true 旗標。

了解更多:有關更多詳細資訊,請參閱 風味指南

iOS 支援

Swift Package Manager 現在是預設值

Swift Package Manager 現在是 iOS 和 macOS 的預設值

從 Flutter 3.44 開始,Swift Package Manager (SwiftPM) 取代 CocoaPods 成為 iOS 和 macOS 應用程式的預設依賴管理員。Flutter CLI 會自動處理此遷移。當您建置或執行應用程式時,CLI 會更新您的 Xcode 專案以使用 SwiftPM,從而無需管理 Ruby 或 CocoaPods 安裝!

了解更多告別 CocoaPods:Swift Package Manager 即將成為 Flutter 的預設值!

Add-to-App 整合也更具彈性。如果您將 Flutter 嵌入到現有的 iOS 應用程式中,新的 flutter build swift-package 命令會將您的 Flutter 應用程式或 Add-to-App 模組打包為 Swift Package,以便在您的原生專案中輕鬆使用。

了解更多:查看 更新的文件,了解如何與 SwiftPM 整合。

如果您的應用程式依賴仍需要 CocoaPods 的 Plugin,Flutter CLI 將會列印警告,並暫時退回到 CocoaPods 以處理這些依賴。我們建議要求這些套件維護者進行更新,因為 CocoaPods 支援最終將完全移除。為了鼓勵生態系統採用,具有 SwiftPM 支援的套件現在會在 pub.dev 評分中獲得額外分數。

如果您是 iOS 或 macOS Plugin 的維護者,您需要將 SwiftPM 支援加入您的套件中。如果您在 2024 年試點期間進行了遷移,請確保您也在 Package.swift 檔案中將 FlutterFramework 加入為依賴項。

如果 SwiftPM 導致您的專案出現重大問題,您可以透過在 pubspec.yaml 中設定 --enable-swift-package-manager: false 來暫時停用它。如果您使用此選擇退出功能,請在 GitHub 上提交錯誤報告並附上您的 Xcode 專案檔案,以便我們進行調查。請注意,此選擇退出功能最終將被移除。

了解更多適用於 Plugin 作者的 Swift Package Manager

Flutter 支援 UIScene

從 iOS 13 開始,Apple 引入了基於「Scene」的生命週期,以支援多視窗體驗。在 WWDC 2025 期間,Apple 宣布使用最新 SDK 建立的應用程式很快將被要求使用 UIScene 生命周期來啟動。此更新對於滿足 Apple 對即將推出的 iOS 版本的需求至關重要。

Flutter 3.44 中沒有新的變更,但我們想提醒您在 Apple 預設開始強制使用此新 API 之前進行遷移。如果您的 AppDelegate 未自訂,Flutter CLI 會自動遷移您的應用程式。但是,如果您的程式碼修改了 UI 生命週期事件,您應該遵循完整的遷移指南。

了解更多UISceneDelegate 遷移指南

iOS 預測文字 (實驗性)

我們正在為文字輸入欄位引入原生 iOS 行內預測文字的實驗性支援 (#183650)。此功能預設是關閉的,但您可以透過啟用 TextField.enableInlinePrediction 來選擇啟用和測試它。啟用後,在您的應用程式中輸入的用戶可以透過按下 Space 鍵來接受 iOS 預測的文字(例如,輸入「My n」並接受「ame」)。請注意,此預測文字的視覺樣式仍在積極完善中,我們感謝您在我們完成此功能時提供的回饋。

了解更多TextField.enableInlinePrediction

網頁

輔助功能

無障礙功能和使用者偏好設定也得到了大幅提升,預設支援瀏覽器的 prefers-reduced-motion 設定以自動停用動畫,同時使用 aria-description 提供表單驗證錯誤的即時螢幕閱讀器回饋。

了解更多prefers-reduced-motion CSS 媒體功能 (mozilla.org)

平台和工具

開發工作流程和瀏覽器整合從未如此流暢。引擎現在透過在焦點轉換時重複使用 DOM 表單來處理 iOS 26 Safari 中的自動填充,同時改進網頁捲軸和鍵盤事件合成以實現穩健的可靠性。此外,CLI 透過將 --base-href 支援直接帶到 flutter run,簡化了網頁應用程式的編排,與生產建置配置相匹配。

了解更多PR #182024PR #179703PR #180692

桌面支援

Canonical 將主導 Flutter 桌面路線圖,並監督我們 Linux、Windows 和 macOS 嵌入器的維護。

我們很高興地宣布與 Canonical 擴大合作關係,Canonical 將擔任 Flutter Desktop 的主要維護者和策略管家。 憑藉其深厚的技術專業知識,Canonical 將主導 Flutter Desktop 路線圖,並監督我們 Linux、Windows 和 macOS 嵌入器的維護。

這次合作僅是更廣泛生態系統擴展的第一步。展望未來,我們正在積極擴大與更多合作夥伴的治理,將 Flutter 的高效能、多平台體驗帶到更多環境和產業。

敬請期待更多關於這次合作的消息!

若要洽詢與 Flutter 團隊合作事宜,請聯絡 [email protected]

視窗 API (實驗性)

⚠️注意:視窗功能目前僅在 main channel 上可用。它們尚未用於生產用途。

Flutter 現在支援跨平台的工具提示和獨立對話框視窗

Canonical 在桌面實驗性視窗 API 方面繼續取得卓越進展!新功能包括:

  • 工具提示:Flutter 現在支援 Linux、macOS 和 Windows 上的工具提示視窗 (#182348#180895#179147)。
  • 彈出視窗:Flutter 現在支援 macOS 上的彈出視窗 (#182371),預計未來版本將支援 Linux 和 Windows。
  • 對話框:Material 的 showDialog 函數現在在支援視窗的平台上建立一個單獨的子對話框視窗 (#181861)。

最後,Linux 現在支援內容大小的視圖 (#182924)。這讓您可以根據內容動態調整視窗大小,這對於彈出式或工具提示視窗很有用。

了解更多:若要搶先預覽桌面實驗性視窗 API,請查看 multiple_windows 範例

Windows 手寫筆支援

使用 Flutter 建立的 Windows 應用程式獲得了針對數位藝術家和筆記記錄者的重大升級!感謝社群成員 CodeDoctorDE 的出色貢獻,Flutter Windows 現在支援手寫筆輸入,包括精確追蹤手寫筆旋轉和壓力感應。

了解更多PR 165323: 允許 Windows 上的手寫筆支援

嵌入式

Toyota

2025 年 Toyota RAV4 是全球最暢銷的汽車。現在,2026 年 RAV4 將使用 Flutter 為其多媒體系統提供動力。

上個月,我經歷了職業生涯中的一個亮點:有機會前往德州普萊諾,參觀 Toyota Motor North America 和 Toyota Connected 辦公室,與工程團隊討論 Flutter 如何改變他們設計、建造和交付多媒體系統的遊戲規則:從辦公室的測試單元到車道上的汽車。作為一名 Flutter 工程師和在一個只購買豐田的家庭中長大的汽車迷,我很高興看到 Flutter 在 2026 年 RAV4 上運行。我在外面看到了這麼多次。(嗯——無處不在??)

感謝 Toyota Motor North America 和 Toyota Connected 團隊的熱情款待!

查看展示影片:

Flutter Outbound 產品經理 Abdallah 和我在 Toyota 測試賽道上拍照!

了解更多:Toyota 的新聞稿,Toyota 多媒體系統的最新演進即將出現在您的螢幕上

LG

LG webOS SDK 將使開發人員能夠建立針對 WebOS 裝置的 Flutter 應用程式

LG 即將推出 webOS SDK,以幫助開發人員輕鬆建立針對 WebOS 裝置的 Flutter 應用程式,賦能 Flutter 在大螢幕及其他領域的應用。

webOS SDK 將包含對 Firebase、影片播放器、遊戲手把等外掛程式的支援。它甚至將支援您熟悉和喜愛的所有 Flutter 功能,例如有狀態熱重新載入和使用 Riverpod 進行狀態管理。

請密切關注未來幾週內這個令人興奮的發佈!

圖形和引擎增強

此版本為 Impeller 後端帶來了有針對性的渲染和效能增強。

Impeller 改進

Vulkan

此版本包括多項 Vulkan 改進,包括更好的快取記憶體管理,以及在掉幀情況下更高效的 GPU/CPU 同步。

使用 SDF 製作更清晰的圓圈

圓圈渲染的數學已更新,以支援使用帶符號距離函數製作更清晰的圓圈。以前它們有時會出現鋸齒,但這個問題已解決。(#183536#183184

增強視覺保真度,利用符號距離函數 (SDF),以確保複雜形狀的高品質、抗鋸齒渲染。

陰影和透視校正

改進了 Impeller 處理透視矩陣的方式,修正了陰影和透視投影變換的渲染行為。(#181434#183187

FragmentShader 改進

感謝以下增強功能,撰寫片段著色器現在更加直觀且不易出錯。

按名稱 API 獲取 Uniform

您現在可以透過名稱而非手動偏移來綁定著色器中的 uniform 變數,大幅簡化著色器程式碼設定:

1
2
3
void setUp(ui.FragmentShader shader) {
shader.getUniformFloat('foobar').set(1.234);
}

了解更多:撰寫和使用 FragmentShadersFragmentShader.getUniformFloat

更清晰的著色器編譯器診斷

著色器編譯器現在在編譯與 Skia 不相容的著色器時會產生警告,幫助您在部署前識別跨平台渲染問題 (#182786#183146)。

框架

此版本平衡了重大的架構轉變與對品質和社群驅動的改進的嚴格關注。當我們開始將 Material 和 Cupertino 函式庫從核心框架策略性地解耦為獨立套件時,核心框架透過網頁渲染的重大更新、基礎穩定性改進和增強的平台整合而繼續成熟。

Material 和 Cupertino 更新

此版本標誌著 Material 和 Cupertino 函式庫的一個重要里程碑。這些函式庫在此版本中已被凍結,代表著這些函式庫在核心框架內的最後一組更新,之後它們將轉換為獨立套件:material_uicupertino_ui。在下一個穩定版本之前,框架中這些函式庫的版本將被棄用,您將能夠遷移到新的、獨立版本控制的套件。

了解更多:有關此轉換的更多資訊,請閱讀 關於凍結的部落格文章 並追蹤 將這些函式庫從核心框架解耦的主要追蹤議題

儘管被凍結,這個版本還是包含了許多改進。一個重要的亮點是 Cupertino 函式庫中選單的現代化。新的 CupertinoMenuAnchor Widget 建立在靈活的 RawMenuAnchor 基礎上,為 iOS 應用程式提供了更穩健和原生感覺的選單體驗 (#182036)。這項工作歸功於社群成員 davidhicks980 的廣泛貢獻,他還創建了 RawMenuAnchor Widget。

CupertinoMenuAnchor 的實際應用範例。

了解更多CupertinoMenuAnchor

在 Material 方面,選單也得到了改進,為 MenuAnchor 類別添加了 Material 3 動畫。這些動畫提供了更流暢、更靈敏的感覺,SubmenuButton 上的新 hoverOpenDelay 參數讓您可以更精確地控制子選單互動。動畫預設禁用,透過設定 animatedtrue 啟用。(#176494)。

MenuAnchor 類別中新增了 Material 3 動畫。

了解更多MenuAnchorSubmenuButton.hoverOpenDelay

此版本還讓 CupertinoSheetRoute 中的可捲軸內容與拖曳動畫無縫協作,實現了捲軸和關閉頁面之間更流暢的過渡 (#177337)。對於需要自訂拖曳區域的開發人員,新的 scrollableBuilder 允許您將受管理的 ScrollController 傳遞給主體的可捲軸區域,以便為您協調頁面拖曳。

CupertinoSheetRoute 中的可捲軸內容與拖曳動畫無縫協作

了解更多CupertinoSheetRouteCupertinoSheetRoute.scrollableBuilder

此版本中,CarouselView 組件在功能上進行了重大改進。它現在支援無限捲軸 (#175710),讓您可以建立無縫循環的輪播。它還具有新的 onIndexChanged 回調和其控制器上的 leadingItem 屬性,當使用者與輪播互動時,可以更好地了解輪播的狀態 (#180667)。

CarouselView 現在支援無限捲軸!

了解更多CarouselView

新的設計原始元件讓實現複雜的 UI 效果變得更容易,例如新的 ShapedInputBorder。這允許 Material Widget 透過指定任何 ShapeBorder 來使用形狀建立輸入邊框。例如,這對於使用 RoundedSuperellipseBorder 以 iOS 樣式顯示 Material 輸入邊框非常有用。(#177220)。同樣,CupertinoFocusHalo 現在支援超級橢圓形狀,確保跨不同 Widget 幾何的一致焦點指示器(#180724)。

了解更多ShapedInputBorder

幾個現有小部件也得到了改進。Expansible 小部件(其底層支援 Material 的 ExpansionTile)現在功能更強大。ExpansibleControllerExpansionTileController 上現在都有一個新的 toggle 方法,並附有改進的文檔和範例(#181320#180273)。此外,Material 的列表圖塊,RadioListTileCheckboxListTileSwitchListTile,現在正確接受 WidgetStatesController,允許對其視覺狀態進行更多程式化控制(#180367)。

輔助功能:為所有使用者提供更具包容性的體驗

使應用程式對每個人都可存取仍然是 Flutter 框架的核心優先事項。此版本引入了與平台特定輔助設定的更深層次整合,提高了語義公告的精確度,並改進了常見 UI 組件的輔助功能。

對於 iOS 開發人員,此版本新增了對幾項新的輔助動作功能的支援 (#178102)。您的應用程式現在可以回應使用者對以下功能的偏好:

  • 自動播放動畫圖片:偵測使用者何時偏好暫停自動播放的 GIF 或其他動畫內容。
  • 自動播放影片預覽:通知應用程式使用者是否已停用影片預覽的自動播放。
  • 偏好非閃爍游標:允許應用程式為覺得閃爍游標分散注意力或難以追蹤的使用者提供穩定的、非閃爍的文字指示器。
  • 這些設定透過 AccessibilityFeatures 物件公開,讓您可以在 iOS 上建立更靈敏和尊重的 UI。

進度指示器也獲得了生活品質的改進。您現在可以使用百分比字串(例如「50%」)作為 ProgressIndicatorSemanticsValue (#183670)。這允許螢幕閱讀器以更自然、更易於閱讀的格式公告進度,而不僅僅是原始十進位值。

此版本還完善了核心 Widget 的語義。Slider Widget 的語義節點已被重構,以更準確地反映其大小和位置,從而改善了透過觸摸探索或輔助設備導航的用戶體驗 (#184168)。此外,對捲軸視圖的修復確保不可見的輔助功能元素不再錯誤地呈現在可捲軸內容之前,從而導致更清晰、更可預測的導航流程 (#184155)。

總而言之,這些變更確保 Flutter 應用程式繼續在所有平台上提供高品質、包容的體驗。

零寬度/高度 Widget 的彈性

此版本的一個主要重點是改進框架在 Widget 渲染為「0x0 環境」時的穩定性——即 Widget 被賦予零寬度或高度的情況,這在以前可能會觸發佈局錯誤或意外崩潰。感謝社群成員 ahmedsameha1 的逐步穩定貢獻,我們為許多核心 Widget 添加了零大小覆蓋,包括 Hero (#180954)、Icon (#181021)、AnimatedPadding (#181235) 和 GridPaper (#180906)。這些更新確保您的應用程式在複雜的佈局轉換或高度受限的視窗中保持彈性。

SelectableRegion 改進

我們已解決 SelectableRegion 中的兩個關鍵問題,以改進原生和網頁平台上的佈局保真度和文字選取行為:

網頁佈局限制保留

以前,SelectableRegion 在網頁上渲染時可能會導致其子項意外縮小。它現在正確地將所有佈局限制未經修改地傳遞給其子項,確保一致的大小調整行為 (#184083)。

多行複製精確度

SelectableRegion 中的文字選取現在更加精確——當使用者選取並複製多行文字時,換行符號現在在複製的輸出中正確保留,而不是遺失 (#184421)。

重大變更和棄用

此版本包含幾個重要的棄用和重大變更,作為持續現代化和改進 Flutter 框架的一部分。

RawMenuAnchor 回調調整

RawMenuAnchor 的某些回呼的呼叫順序已調整,以允許更靈活和可預測的自訂。

了解更多更改 RawMenuAnchor 關閉順序

此版本中的主要棄用項目包括:

  • CupertinoSheetRouteshowCupertinoSheetCupertinoSheetRoute 中的 builderpageBuilder 參數現在已被棄用,取而代之的是 scrollableBuilder (#177337)。此變更允許更好地整合可捲動內容與工作表的拖曳動畫。
  • ReorderableListViewonReorder 回呼已被棄用,取而代之的是更精確的 onReorderItem (#178242)。新的回呼提供了一個更可預測的 newIndex,該 newIndex 考慮到項目在重新插入之前被移除的情況。
  • 工具:Flutter 工具中的 --web-hot-reload 旗標現在已被棄用,因為網頁的熱重新載入現在透過更現代的機制處理 (#181884)。此外,plugin_ffi 模板已被棄用,取而代之的是支援 FFI 的更穩健的 Plugin 模板 (#181588)。

了解更多:有關這些及其他變更的更多詳細資訊和遷移指南,請參閱 flutter.dev 上的 重大變更頁面

Flutter 無處不在,日復一日。

Flutter 的觸及範圍廣及行動、桌面、網頁和嵌入式系統,儘管個別功能令人印象深刻,但它們共同為開發人員提供了一個強大的平台,賦予超過 150 萬名開發人員能力,建立令人難以置信的使用者體驗,這些體驗無處不在,日復一日地被使用。您可以在從業務工具和日常應用程式中找到 Flutter,例如 NotebookLMTalabatZohoKaraca,到 2026 年 Toyota RAV4 和 LG 的 webOS 裝置資訊娛樂系統等高調嵌入式實作。

Flutter 由每個人建造,為每個人服務。

Flutter 的成功建立在您的回饋之上!我們致力於保持對話——無論是透過評論、議題還是我們即將進行的開發者調查。您的意見是推動您喜愛功能的原因,所以請繼續與我們分享。

這個生態系統依賴於 LG、豐田和 Canonical 等行業領導者,最重要的是,依賴於每天使用 Flutter 建立應用程式的超過 150 萬開發人員。我們非常高興能繼續共同建立和發展這個精彩的 Dart & Flutter 生態系統。

若要試用所有新功能、優化和圖形增強功能,只需簡單地:

1
flutter upgrade

【文章翻譯】Flutter’s multiplatform value for agentic development

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

Flutter 多平台對於代理開發的價值

Flutter 多平台開發的核心價值在於僅使用單一、共享的原始碼庫來構建支援多平台的應用程式,讓開發團隊能夠在所有平台上協同工作。

這在人工智慧驅動的世界中至關重要,因為增強的一致性、減少的令牌使用量和快速的市場觸及變得至關重要。透過維護單一程式碼庫,開發人員可以將其人工智慧助手集中在一個統一的語境中,大幅減少令牌開銷,並最大限度地減少人工智慧幻覺。開發人員無需讓人工智慧在零碎的、平台特定的語言之間翻譯功能,而是可以利用人工智慧在 Dart 中一次性撰寫程式碼並立即部署到任何地方。

Dash secretly hanging out in an alley doing agentive things

現有價值主張

多平台開發依賴於啟用單一、共享的原始碼庫。在我們的第一方 Flutter 應用程式中,95% 到 99% 的原始碼是共享的。這種大量的程式碼重用帶來了以下幾個優點:

  • 由於團隊只需要維護一個程式碼庫,因此可以更快地在多個平台上推出產品。
  • 保證跨平台的一致性,為公司提供單一、一致的功能集,無論客戶選擇哪個平台,都能獲得支援。
  • 原生效能和穩定性,因為 Flutter 程式碼會編譯成每個平台的原生機器碼。
  • 語義保護措施提高安全性,因為 Dart 語言是強型別的。

代理價值主張

雖然大型語言模型(LLMs)擅長將需求轉化為程式碼,但使用它們為每個平台構建單獨的原生應用程式的擴展性很差。使用 LLMs 在不同語言之間複製功能會增加生成時間和令牌使用量,並可能很快導致實作方案產生差異。

Flutter 的單一來源解決方案消除了這些問題。但除了程式碼共享之外,Flutter 的特定架構使其成為代理驅動開發的理想框架。這種新興的價值主張是由幾個關鍵優勢驅動的:

  • 令牌減少: 透過在 Dart 中一次性生成應用程式,與使用 AI 在平台特定語言之間翻譯功能相比,您可以大幅減少令牌開銷。這消除了在不同程式碼庫之間複製邏輯的需要,這種做法擴展性差且會增加令牌使用量。
  • 一致性: Flutter 提供統一的體驗,因為單一來源程式碼庫確保所有平台上的功能集保持一致。這可以防止當 LLMs 產生幻覺且實作方案產生差異時出現的平台差異。
  • 自我修正代理: Flutter 由於 Dart 的強型別語言和豐富的開發者工具,具有強大的語義保護措施。當 AI 代理生成程式碼時,透過彈性工具和 MCP 伺服器暴露的嚴格型別系統會充當即時回饋循環,以立即捕獲錯誤。
  • 可預測的程式碼生成: LLMs 擅長生成層次化、結構化的資料。Flutter 的組合式、宣告式 UI 與此優勢相符。代理更容易推理並可靠地生成單一 Dart widget 樹,而不是管理其他平台特定框架的零碎邏輯。
  • 透過熱重載實現高速驗證: 在代理工作流程中,瓶頸通常是驗證 AI 的輸出。Flutter 的熱重載功能提供了一個工作流程,其中代理所做的任何更改都可以在開發過程中在運行中的應用程式中立即看到。

Flutter 的優勢

Flutter 支援針對多個平台的單一共享程式碼庫,再加上強型別語言和強大的工具,使其成為代理驅動開發的絕佳搭檔。總之,未來一片光明!借助 Flutter,期待您的代理開發應用程式能夠實現低令牌使用量、更快的跨平台開發週期、強大的語義保護措施、跨平台的應用程式一致性以及原生效能。祝您開發愉快!


Flutter 在代理開發中的多平台價值 最初發佈於 Flutter on Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

【文章翻譯】New updates to A2UI and Flutter’s GenUI package

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

生成式使用者介面 (Generative UI,簡稱 GenUI) 是一種使用者體驗模式,其中代理程式不僅會生成內容,還會決定如何向使用者顯示內容並使其具有互動性。對於 Flutter 開發人員來說,實作 GenUI 意味著使用 A2UI,這是一個開放協議,定義了代理程式和客戶端 (或「渲染器」) 之間如何協同合作以組成和維護使用者介面。為了利用這一點,Flutter 團隊開發了 genui,這是一個使用 A2UI 與代理程式連接並為其提供 Widget 目錄以供使用,然後將這些 Widget 呈現給使用者的套件。

genui 套件和 A2UI 協議最近都獲得了更新!

genui 的最新版本引入了架構上的多項變革。受 A2UI 協議 v0.9 採用的推動,此次更新將 genui 從「結構化輸出優先」的理念 (其中 A2UI 訊息透過結構化輸出 API 串流傳輸) 轉變為「提示優先」的方法 (其中代理程式將 JSON 區塊作為文字包含在其回應中)。它還解耦了架構,提供了對應用程式如何與大型語言模型 (LLM) 互動的更直接控制。

如果您要將應用程式從 genui 套件的 v0.7.0 遷移到 v0.9.0,本指南涵蓋了必要的步驟,從依賴項清理到連接新的聊天循環。

架構解耦

在之前的版本中,GenUI 依賴於一系列基於 ContentGenerator 的類別。這些類別隱藏了提示建構、LLM 網路呼叫和回應解析的細節。

package:genui 的最新版本移除了 ContentGenerator。相反,框架現在分為不同的層次:

  • 引擎 (SurfaceController):管理 UI 的狀態和渲染。
  • 傳輸 (A2uiTransportAdapter):在代理程式和渲染器之間串流傳輸訊息。
  • 外觀 (Conversation):提供用於管理聊天狀態的高階 API。

這種解耦意味著您可以控制聊天歷史記錄、重試邏輯和錯誤處理。這也意味著您可以隨意設定與 LLM 的連接。框架不再使用 ContentGenerator「包裝」您的代理程式,因此您可以自由使用您喜歡的模型和提供者,調整生成設定,添加自己的函數等等,而無需透過框架的 API 來完成。

由於 ContentGenerator 已不復存在,因此不再需要特定於提供者的包裝套件。如果您提取套件的最新版本,您會發現諸如 genui_dartantic、genui_google_generative_ai 和 genui_firebase_ai 等名稱不再出現在樹中。

這是遷移中最重要的程式碼變更。您的應用程式負責建立與代理程式的連接,並透過 TransportAdapter 來回傳遞訊息,而不是將 ContentGenerator 傳遞給 SurfaceController。

舊方法:

1
2
3
4
5
6
7
8
9
10
11
// 建立一個 ContentGenerator,封裝與代理程式的互動。
final generator = FirebaseAiContentGenerator(
catalog: CoreCatalogItems.asCatalog(),
systemInstruction: 'You are a helpful assistant.',
);

// 建立一個會話,將生成器與管理表面、更新等的 GenUiManager 連結。
final conversation = GenUiConversation(
genUiManager: GenUiManager(catalog: catalog),
contentGenerator: generator,
);

新方法:

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
final catalog = BasicCatalogItems.asCatalog();

// 建立一個 SurfaceController 來管理生成表面的狀態。
final surfaceController = SurfaceController(catalogs: [catalog]);

// 建立一個傳輸適配器,將來自 `genui` 庫的訊息路由到代理程式,
// 然後透過 `addChunk` 將回應回傳到適配器。
late final adapter = A2uiTransportAdapter(
onSend: (ChatMessage msg) async {
// 使用字串緩衝區準備要傳送給代理程式的 token。
final buffer = StringBuffer();

// 迭代 `genui` 套件建立的訊息,並將它們作為 token 添加到緩衝區。
for (final part in msg.parts) {
if (part.isUiInteractionPart) {
buffer.write(part.asUiInteractionPart!.interaction);
} else if (part is genui.TextPart) {
buffer.write(part.text);
}
}

// 將內容生成請求傳送給代理程式,包括來自 `genui` 的字串化訊息。
final response = await myAgentClient.sendRequest(buffer.toString());

// 收到代理程式的回應後,使用 `addChunk` 將其添加到 `genui` 套件的輸入流中,
// 在那裡它將被解析以獲取 A2UI 訊息。
adapter.addChunk(response);
},
);

您可能會看著這兩個範例並想:「等等,API 改進不應該意味著我必須撰寫 更少 的程式碼而不是更多嗎?」 的確,以前連接代理程式的這部分「連線」程式碼包含在 genui 套件中,隱藏在 ContentGenerator 類別中,但新方法有一些具體的優點:

  • 無需 ContentGenerator,您可以按照自己的喜好設定代理程式,將其保留在您喜歡的記憶體中,並管理其生命週期。您還可以幾乎隨意使用任何您喜歡的 AI 來源,而無需等待帶有新 ContentGenerator 的套件更新。
  • 您不再需要將與代理程式的連接「注入」到 genui API 中。它們是鬆散耦合的,只有 token 來回移動。
  • 測試更簡單。genui 直接接受 token,它們可以來自代理程式、模擬代理程式或硬編碼測試。
  • 如果您想將連接封裝到類別中,仍然可以這樣做。事實上,genui 的幾個範例 採用了這種方法。

提示優先

在以前的版本中,genui 套件嚴重依賴 LLM 提供者嚴格的 API 級別限制 (例如「JSON 模式」或複雜的函數呼叫定義) 來強制模型輸出有效的 UI 結構。綱要透過特定的 API 參數帶外傳遞給 LLM,LLM 實際上被鎖定在一個嚴格的結構中。

雖然這引導模型建立可預測、格式良好的 JSON,但深度巢狀的綱要有時可能會混淆模型或與其自然文字生成傾向相衝突。此外,對結構化輸出的依賴限制了目錄的整體大小和複雜性。這也使得偵錯更加困難,因為約束完全存在於網路層中,而不是您可以在純文字中輕鬆讀取和調整的內容。

「提示優先」方法將真相的來源轉移回 LLM 擅長的地方:系統指令。UI 綱要和與 A2UI 相關的指令不是完全依賴嚴格的 API 開關,而是直接以純文字形式注入到 LLM 的系統提示中。LLM 讀取指令,詳細說明如何為客戶端建構訊息。

這種方法有幾個優點。首先,現代 LLM 經過高度優化,可以遵循詳細的系統指令和範例。在提示中提供綱要與它們的「思維」方式一致。此外,由於 UI 綱要現在只是您提示中的純文字,您可以根據應用程式的需求進行更改。

這項變更表示將正確的提示放入代理程式的上下文視窗的責任現在落在您的應用程式上。幸運的是,genui 套件提供了一個新工具來幫助您為應用程式建立正確的系統提示:PromptBuilder。給定一個目錄和您想提供的任何其他指令,PromptBuilder 將建立一個系統提示,其中包含您的 LLM 需要正確格式化 A2UI 訊息的綱要定義和規則。

1
2
3
4
final promptBuilder = PromptBuilder.chat(
catalog: catalog,
systemPromptFragments: ['You are a helpful assistant.'],
);

設定完成後,您的應用程式可以使用 promptBuilder.systemPrompt 取得提示的 String 版本,然後將該值傳遞給 LLM。

協定與綱要調整

如果您的程式碼手動建構 A2UI JSON 或依賴特定的有效載荷結構,請注意 A2UI v0.9 更新中的這些重大變更:

  • 表面建立: beginRendering 現已更名為 createSurface
  • 平面組件定義: 不再使用巢狀鍵 (例如 {“Text”: {“text”: “Hello”}}),組件現在使用平面識別符號:{“component”: “Text”, “text”: “Hello”}
  • 資料綁定: 綁定已簡化。使用 { "path": "/path/to/var" } 進行路徑解析。

屬性重新命名:

  • distribution => justify
  • alignment => align
  • usageHint => variant
  • text (in TextField) => value
  • userAction => action

其他項目也重新命名了!

除了其他一些小調整之外,幾乎所有核心類別的 GenUi 前綴都已移除:

  • GenUiConversation => Conversation
  • GenUiController => SurfaceController
  • GenUiSurface => Surface
  • GenUiHost => SurfaceHost
  • GenUiContext => SurfaceContext
  • GenUiTransport => Transport
  • GenUiFallback => FallbackWidget

此外,CoreCatalogItems 更名為 BasicCatalogItems,以闡明它作為基準實作而非嚴格要求。

最後,為了與標準 LLM 函式呼叫術語保持一致,GenUiFunctionDeclaration 和對「工具」的引用已更名為 ClientFunction。

新的 genai_primitives 套件

genui 套件不再附帶自己的訊息類型。相反,GenUI 團隊建立了一個新的 genai_primitives 套件,其中包含 GenAI 應用程式所需常見功能的原始類型。此套件包含 ChatMessage、MessagePart 和 ToolDefinition 等類型。

這些新的類型在 genui 套件 API 中使用,它們足夠靈活,可以融入您可能正在開發的其他 GenAI 應用程式或套件中。

還有更多!

除了上述內容之外,最新版本的 A2UI 和 genui 套件還帶來了幾個新功能,例如:

  • 自訂函數,用於驗證客戶端上的資料。
  • 新的模組化綱要。
  • 改進的錯誤處理。

有關這些的更多資訊,請查看 v0.9 發佈部落格文章 並前往 a2ui.org

總結

genui 的最新更新引入了一種更加慣用、靈活和穩健的架構。如果您尚未開始使用 GenUI,現在是最好的時機!前往我們的 入門程式設計教學 以獲取對該技術的實作理解,並在大約 90 分鐘內建立一個可運行的應用程式。


A2UI 和 Flutter 的 GenUI 套件的新更新 最初發佈於 Flutter 上的 Medium,人們在那裡透過突出顯示和回應此故事來繼續討論。

【文章翻譯】Introducing Skills for Dart and Flutter

【文章內容使用 Gemini 2.5 Flash 自動翻譯產生】

介紹預打包的 Dart 和 Flutter 技能!

透過領域專業知識改進 AI

AI 代理是通才,但對於專業的 Flutter 開發來說,「通才」還不夠。要建構生產級應用程式,您需要一個了解在地化細微差別、最新 Dart 語言功能以及如何新增整合測試的助理。

今天,我們將推出適用於 Flutter 和 Dart 的 代理技能——一種為您的 AI 工具提供領域特定專業知識的新方法。

超越知識差距

AI 開發的主要挑戰之一是「知識差距」。Flutter 和 Dart 發布新功能的速度可能比 LLM 更新其固定訓練資料的速度更快。作為 我們對 AI 的思考 的一部分,我們正在尋找方法,不僅要解決知識差距,還要確保代理應用這些知識以準確有效地完成任務,並遵循最優化的工作流程。

大約一年前,模型上下文協定(MCP)是提供更多 AI 領域特定專業知識的方法。雖然 MCP 讓代理能夠存取專業工具,但代理技能教會代理 如何 使用這些工具來完成特定任務。這樣想:MCP 提供錘子和釘子(工具),而技能則提供建造房屋的藍圖和專業知識。

技能透過「漸進式揭露」提高上下文效率。這類似於 Flutter 中的延遲載入,應用程式可以在需要時載入函式庫,編碼代理在相關時載入技能,以執行您正在嘗試執行的操作。

對於 Flutter 和 Dart,這些技能提供了針對常見工作流程的量身訂製指令,並增強了 Dart MCP 伺服器中提供的工具,以縮小知識差距,從而提高準確性並降低 Token 使用量。

一種任務導向的方法

我們的早期實驗表明,僅提供文件資料的技能並沒有像我們最初假設的那樣增加那麼多價值。由於 Flutter 全面且寫得很好的文件是開源的,現代模型已經能夠高效地為大多數問題和任務找到相關資訊。

因此,我們轉向建立「任務導向」的技能。我們 GitHub Flutter SkillsDart Skills 儲存庫中的每個技能都專注於開發人員任務,例如透過提供代理可靠完成任務的指令來建立自適應佈局。我們已經進行了廣泛的手動評估來定義我們的初始技能集,並且正在開發一個自動化評估管道,我們將很快分享。

使用技能

若要開始在您的工作流程中使用這些技能,請先在您的專案目錄中安裝技能集:

1
2
npx skills add flutter/skills - skill '*' - agent universal
npx skills add dart-lang/skills - skill '*' - agent universal

您將被要求選擇要安裝的技能。選擇全部或選擇您可能覺得最有用的特定技能。

然後選擇您偏好開發的代理。

現在,像往常一樣提示您的 AI 代理。以下是您今天可以使用這些技能的 5 種方法:

技能 #1:flutter-add-integration-test

設定 Flutter Driver 以進行應用程式互動,並將 MCP 操作轉換為永久整合測試。

1
為我的應用程式中的結帳流程添加整合測試

技能 #2:flutter-setup-localization

為您的 Flutter 專案添加在地化支援

1
在我的應用程式中設定在地化

技能 #3:flutter-build-responsive-layout

使用 LayoutBuilder、MediaQuery 或 Expanded/Flexible 建立可適應不同螢幕尺寸的佈局。

1
確保結帳畫面使用響應式佈局

技能 #4:dart-use-pattern-matching

重構程式碼以在適當的地方使用 Dart 的模式匹配語言功能

1
重構我的程式碼,使其在可能的情況下使用模式匹配

技能 #5:dart-collect-coverage

使用 coverage 套件收集單元測試覆蓋率並生成 LCOV 報告。

1
收集我的專案的測試覆蓋率

有關更多提示範例,請查看 GitHub 上的 Flutter SkillsDart Skills 儲存庫中的 readme。

告訴我們您的想法

這些最初的核心技能,旨在處理最常見的 Flutter 開發障礙,僅僅是個開始。我們希望與您,我們的社群,一起建立 AI 輔助開發的未來。當您使用這些技能並為您的專案建立新技能時,請提交議題(Dart Skills 儲存庫Flutter Skills 儲存庫),並告訴我們您希望看到哪些額外的工作。我們期待幫助您在使用這些技能時提高工作效率!


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