0%

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

與 GitHub 合作,為 Dart 套件提供供應鏈安全性

從今天開始,GitHub 在其諮詢資料庫相依關係圖Dependabot 中支援 Dart。這表示 GitHub 現在為 Dart 和 Flutter 應用程式的供應鏈安全性提供全面支援。

要了解這些新功能,請查看 GitHub 部落格文章。要了解這對身為 Dart 開發人員的您意味著什麼,請繼續閱讀。

“隨著 Dart 現在加入我們的供應鏈安全生態系統,GitHub 擴展了其對快速成長的開源社群的支援,”GitHub 資深產品經理 Courtney Claessens 表示。“透過將安全性左移,我們不僅幫助開發人員,還幫助數百萬依賴於 Dart 開發的應用程式的使用者。”

了解套件安全問題

想像一下,您正在構建一個很棒的 Flutter 應用程式。您在 pubspec 中使用了許多非常好的套件(例如 像這樣),並將您的應用程式發佈到多個商店。如果其中一個套件有一個重要的更新來修復安全漏洞,會發生什麼事?您如何才能知道這一點?除了定期手動檢查數十個套件的 CHANGELOG 之外,您無法做到這一點。這是一個真正的挑戰。

這就是 Dependabot 的用武之地。如果您在 GitHub 儲存庫中管理您的原始碼,相依關係圖和 Dependabot 會監控您的 pubspec 相依關係,並讓您知道是否錯過了更新。Dependabot 會提交一個拉取請求,代表您將 pubspec.yaml 更新到套件的最新版本。這一切都是透過 GitHub 中新的 Dart 特定改進實現的。

Dependabot 發送一個 PR 來提升(更新)套件相依關係到更新的版本。
相依關係圖顯示 Dart 套件的相依關係集合。

Dart 套件的諮詢資料庫

此場景依賴於一個高品質的開放安全諮詢資料庫,其中列出了 Dart 套件中已知的漏洞。為此功能,我們與 GitHub 合作,將 Dart 支援加入到他們熱門的 GitHub 諮詢資料庫 中。該資料庫已經包含了數千個其他生態系統(如 npm、NuGet 和 Maven)的諮詢。

從今天開始,您現在可以在為已發佈的 Dart 套件建立諮詢時選擇 Pub 生態系統。

為發佈在 pub.dev 上的 Dart 套件建立新的安全諮詢。

如果您在 pub.dev 上發佈套件,我們建議兩個新的最佳實務。

  1. 使用 GitHub 的 安全諮詢 功能在您的 GitHub 儲存庫中建立新的諮詢。GitHub 會將這些諮詢納入到中央 GitHub 諮詢資料庫中。
  2. 設定您的 安全策略,包括詳細說明使用者如何回報漏洞。

立即保護您的 Dart 儲存庫

新的安全功能現已推出。如果您的原始碼位於公共儲存庫中,Dependabot 已開始監控安全問題。如果您的程式碼位於私有的 GitHub 儲存庫中,您需要更多 設定 才能啟用此功能。


與 GitHub 合作,為 Dart 套件提供供應鏈安全性 最初發佈在 Dart 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

研究 Flutter 開發人員的 IDE 使用情況

2022 年第二季使用者調查結果。作者:李家 Young 和 Ander Dobo

Google 的 Flutter 團隊目前為 Android Studio(基於 IntelliJ-IDEA)和 Visual Studio Code(VS Code)建立和維護支援。我們在這些 IDE 的插件中整合了 Flutter 應用程式開發功能,例如程式碼完成、語法高亮、Widget 編輯輔助、運行和除錯支援等等。自 Flutter 最初推出以來,Flutter 開發人員一直使用這兩種 IDE,Android Studio 傳統上比 VS Code 更受歡迎。如以下圖所示,VS Code 的普及速度比 Android Studio 快,最近在 Flutter 開發中也超越了 Android Studio 的普及程度。

為了更好地了解 Flutter 開發人員在 IDE 選擇背後的思考,Flutter UX 團隊在 2022 年 5 月針對這個主題進行了一項調查。

  • 在本文的其餘部分,「Android Studio」代表 Android Studio 和 IntelliJ-IDEA。
圖 1. 從 2021 年 8 月到 2022 年 7 月,來自每個 IDE 的 Flutter 開發人員數量顯示,VS Code 在最近幾個月變得更加流行。

我們之前對 IDE 的了解

除了 Flutter 開發人員在 2022 年初在 Android Studio 和 VS Code 之間的比例為 50:50 之外,我們還根據之前的調查對開發人員的選擇有了更多了解。

Flutter 開發人員傾向於使用他們熟悉的 IDE

在 2019 年第三季,我們詢問 Flutter 開發人員為什麼他們最喜歡他們使用的 IDE。最常見的選擇是 IDE 對他們來說「更熟悉」。

圖 2. 根據 2019 年第三季的調查結果,80% 的 Android Studio 使用者和 61% 的 VS Code 使用者表示,他們選擇 IDE 是因為熟悉度。

VS Code 使用者重視他們在 IDE 中體驗的速度

上述圖表(圖 2)的另一個值得注意的地方是,68% 的 VS Code 使用者選擇 IDE 是因為它比其他 IDE 快,而只有 12% 的 Android Studio 使用者這麼認為。在一個開放式問題中,VS Code 使用者表示他們喜歡 IDE,因為它輕量級但有很多擴展。

VS Code 使用者對 Flutter 的 IDE 支援感到更滿意

我們還詢問了對 Flutter 的 IDE 支援的滿意度,VS Code 使用者往往更滿意。(當開發人員從 IDE 中打開調查時,我們會記錄他們使用的 IDE。當開發人員點擊調查連結時,我們會通知他們有關此記錄。)

圖 3. 93.3% 的 VS Code 使用者對 Flutter 的 IDE 支援感到滿意,而只有 85.9% 的 Android Studio 使用者感到滿意。

當然,Android Studio 是專門為 Android 開發而設計的完全整合 IDE,因此它在這個目的上具備更豐富的功能集。開發人員表示,在 Android Studio 中處理原生 Android 程式碼和使用重構等便利功能很容易。在下一節中,我們將更深入地探討偏好,以及為什麼開發人員對這些優勢感到不滿意,而沒有在 Android Studio 中使用 Flutter。

我們從 2022 年第二季調查中學到了什麼

上述結果讓我們想知道,為什麼 Flutter 開發人員對 VS Code 的支援比對 Android Studio 的支援更滿意。我們想要了解 Flutter 開發人員真正喜歡 VS Code 的地方。

為了了解這一點,我們向開發人員詢問了一組問題,這些開發人員將他們的首要 IDE 從一個 IDE 切換到另一個 IDE,無論方向如何。我們相信這些開發人員能夠從他們的角度告訴我們每個 IDE 中的獨特價值。

首先,將主 IDE 從 Android Studio 切換到 VS Code 的 Flutter 開發人員更多。

圖 4. 將主 IDE 從 Android Studio(藍色)切換到 VS Code(青綠色)的 Flutter 開發人員比反過來多。

如以下圖表所示,那些切換到 VS Code 的開發人員喜歡它的效能(82%)和可用性(63%)。另一方面,那些切換到 Android Studio 的開發人員喜歡它的功能(51%)、與 Flutter 工具的整合(39%)和原生平台(27%)。

圖 5. 切換到新 IDE 的原因。

儘管如此,約有 23% 的 Flutter 開發人員同時使用 VS Code 和 Android Studio。當我們詢問他們為什麼使用不止一個 IDE 時,出現的最突出的主題是 VS Code 使用者需要使用 Android Studio 和 Xcode 才能實現特定於原生的功能,例如模擬器設定、構建配置、發佈要求(例如金鑰生成和簽署),以及在開發混合 Flutter+原生應用程式時。

圖 6. 22.5% 的 Flutter 開發人員同時使用 VS Code 和 Android Studio。

我們從調查中獲得的另一個見解是,來自不同國家或地區的 Flutter 開發人員偏好不同的 IDE。雖然大多數 Flutter 開發人員更喜歡 VS Code 而不是 Android Studio,但來自中國大陸的開發人員更喜歡 Android Studio(56%)而不是 VSCode(23%)。我們發現這很有趣——Flutter 在全球範圍內被採用,但在不同的開發環境中使用。如果您有來自您國家或地區的任何故事要與我們分享關於這種趨勢的資訊,請在本文下方留言。

圖 7. 按國家或地區劃分的 IDE。包含至少 100 位調查受訪者的國家或地區。

總結

我們的目標是提供一個有用且完整的開發體驗,最大限度地減少開始使用 Flutter 的摩擦,並最大限度地提高開發人員的生產力。我們將考慮這些和未來的研究結果,為未來 Flutter IDE 支援和文件制定路線圖。作為第一步,我們正在對網站的入門文件進行一些小的更新,以反映上述 IDE 偏好和使用模式。

我們從這項調查和其他調查中獲得的見解對我們來說非常寶貴,並確保我們投資於正確的領域,以繼續改善 Flutter 開發人員體驗。感謝所有參與的使用者!如果您有興趣參加未來的使用者研究,您可以透過 https://flutter.dev/research-signup 註冊。我們將在下個季度回來分享第三季度的調查結果。下篇文章見!


研究 Flutter 開發人員的 IDE 使用情況 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。

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

在 Flutter Vikings 大會上宣布 Flutter 3.3

來自美麗的挪威首都奧斯陸的問候,Flutter 社群的成員們正聚集在 Flutter Vikings 大會。Flutter Vikings 是一個為期兩天的由社群驅動的開發者活動,有來自世界各地的專家的三個內容曲目。迄今為止,已有超過 5,000 名開發者註冊,雖然現場活動已售罄,但您仍然可以 免費觀看所有線上課程

Flutter 不斷成長,無論是在使用率還是生態系統規模方面。每天,都有超過 1,000 個使用 Flutter 研發的手機應用程式被發佈到 Apple 和 Google Play 商店,以及更多在網頁和桌面上的使用。而 Flutter 套件生態系統 現在包含超過 25,000 個套件,進一步證明了它的成熟度和廣泛性。

The Dash mascot and her friends celebrating the launch of Flutter 3.3.

今天我們宣布 Flutter 3.3。 這個版本重點放在強化 Flutter 3 中發佈的功能的細化和效能改進。它擴展了對不斷發展的 Material 3 規範的支援,包括幾個新的元件和許多錯誤修復,並且包含針對平板電腦和桌面開發者的新功能,包括 iPad 上的塗鴉手寫支援、可選文字分組和觸控板支援。這個版本還包含 Dart 2.18,它為使用 Swift 或 Objective-C 編寫的程式庫和程式碼引入了 FFI 支援。針對此版本構建的應用程式將在桌面、網頁和行動裝置上體驗到效能提升,因此我們鼓勵您運行 flutter upgrade 以在所有開發者工作站上獲取最新版本!

若要深入了解所有新功能和改進,請查看 Flutter 3.3 發行說明Dart 2.18 宣布部落格文章

Wonderous:一個新的參考應用程式

gskinner 的設計團隊合作,今天我們推出 Wonderous,一個專門用來展示 Flutter 的能力,可以無縫交付高階、美麗的體驗的應用程式。即使它展示了 Flutter 的強大功能,我們也共同打造了 Wonderous,使其本身成為一個美麗的應用程式。從印度阿格拉令人驚嘆的泰姬瑪哈陵到墨西哥尤卡坦半島的奇琴伊察瑪雅遺址,Wonderous 將世界上一些最非凡的地方帶到您的手機上,使用影片和影像探索藝術、歷史和文化的交匯點。

Navigate to the intersection of history, art, and culture. The Wonderous app has been designed to support various accessibility aids.

Wonderous 是一個我們希望您與家人和朋友分享的應用程式,但它也是一個您可以作為開發者探索的開源專案。作為一個真實世界的應用程式,它提供了一系列視覺技巧和最佳實務的綜合示例,我們認為這些技巧和實務會激勵中級到高級開發者。在接下來的幾週裡,gskinner.com 團隊將分享更多有關應用程式製作的技術文章,包括對無障礙功能的支持、可泛化的動畫技巧以及效能的提示和技巧。

若要進一步了解我們開發 Wonderous 的動機,以及與其相關網站、Android 和 iPhone 應用程式以及原始碼的連結,請查看 Flutter 部落格上的 獨立文章

Impeller:我們的全新圖形引擎

除了 3.3 本身的改進之外,團隊一直在努力開發 Impeller我們的下一代渲染層

Impeller 是對 Flutter 引擎核心部分的大規模重寫,它用自訂運行時替換了以前的 Skia 程式碼,該運行時充分利用了現代硬體加速圖形 API,例如 iOS 上的 Metal 和 Android 上的 Vulkan。它提供絲般順暢的動畫,大幅提升了應用程式可以從多平台 UI 工具包中期待的水平。這種差異是直觀的,使用 Impeller 的應用程式可以期待能夠比以前更進一步地突破界限,同時保持鎖定在 60Hz 或更快的更新率。最值得注意的是,Impeller 完全消除了對運行時著色器編譯的需要,而這正是當今應用程式中造成畫面更新率「卡頓」的常見原因。

雖然它尚未完成所有功能,並且我們仍在優化效能,但我們現在正在 Google 級別的應用程式上進行內部測試。如果您從 Apple App Store 下載 Wonderous for iPhone,您將在一個產品級別的應用程式上看到 Impeller 的實際運行。

我們很興奮地宣布,現在可以將 Impeller 作為 iOS 上的早期採用者預覽版提供。 Impeller 不需要更改您的程式碼,除了 啟用標誌 之外。有關 Impeller 架構和如何啟用的更多資訊,請 參閱我們的 Wiki。在開發過程中,Impeller 的早期採用者應該切換到 Flutter 的 master channel,以確保您使用的是最新的程式碼。

我們期待看到利用 Impeller 中的效能和品質改進的應用程式和演示。我們也欣賞 可重現的議題報告,這些報告顯示了當前構建中的效能或保真度回歸。

向 Eric 告別

最後,我們向 Eric Seidel 表示溫暖的告別,他是 Flutter 的聯合創始人之一,本月將離開 Google,開始新的冒險。Eric 是第一個向世界介紹 Flutter 的人,當時它還沒有名字或吉祥物,是在 2015 年的 Dart 開發者峰會 上;他管理了 Flutter 工程團隊的大部分時光,簡而言之,沒有 Eric,就不會有我們所知的 Flutter。

但 Eric 有一顆企業家的心,他的「超級力量」(用他最喜歡的詞之一來說)是作為一個創造者和發起者。因此,當他分享他的創業計畫時,並沒有讓人感到意外。因此,當他離開巢穴,開始他的下一個冒險時,我們向他送去我們的鼓勵和感謝。

以摘錄自 Flutter 1.0 發佈活動 的內容來結束這篇文章,在該活動中,Eric 分享了我們對 Flutter 的願景:一個長期的賭注,我們可以徹底改進構建美麗使用者體驗的體驗。這仍然是我們的願景,並且我們尚未完成。隨著來自世界各地的數百萬開發者依賴它,一個由數千名貢獻者組成的生態系統,以及 Google 的團隊蓬勃發展和壯大,我們希望您能繼續加入我們的旅程!


在 Flutter Vikings 大会上宣布 Flutter 3.3 最初发布于 Flutter 的 Medium,人们在那里通过突出显示和回应这个故事来继续讨论。

http://creativecommons.org/licenses/by/4.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,人們在那裡透過突出顯示和回應這個故事來繼續討論。