【文章內容使用 Gemini 1.5 Pro 自動產生】
Flutter 3.7 新功能:Material 3 更新、iOS 改進等等!
我們很高興在 2023 年開始時發佈 Flutter 3.7!在 Flutter 3.7 中,我們作為社群,繼續改進框架,加入了一些很棒的新功能,例如:建立自訂選單列、階層式選單、更好地支援國際化的工具、新的除錯工具等等。
我們還繼續完善一些功能,例如全局選取、透過 Impeller 進行更快渲染、DevTools,以及始終如一的效能!
讓我們一起踏上快速旅程,探索 Flutter 3.7 中的新功能吧!
增強的 Material 3 支援
Material 3 支援在 3.7 中得到了極大的增強,以下 Widget 已遷移:
- Badge
- BottomAppBar
- Filled 和 Filled Tonal 按鈕
- SegmentedButton
- Checkbox
- Divider
- Menus
- DropdownMenu
- Drawer 和 NavigationDrawer
- ProgressIndicator
- Radio 按鈕
- Slider
- SnackBar
- TabBar
- TextFields 和 InputDecorator
- Banner
若要使用這些新功能,只需在應用程式的 ThemeData Widget 中開啟 useMaterial3 旗標。若要充分利用 M3 支援,您需要完整的 M3 色彩方案。您可以自己提供,使用新的 主題建構工具,或者 Flutter 可以使用 ThemeData 建構函數的 colorSchemeSeed
參數從單個種子顏色為您生成一個:
1 | MaterialApp( |
有關 Flutter 的 Material 3 支援的最新資訊,請查看 GitHub 上的 總體議題。
若要親自試用這些元件,請查看 互動式演示,展示了所有新的 M3 功能:
選單列和階層式選單
Flutter 現在可以建立選單列和階層式上下文選單。
對於 macOS,可以使用 PlatformMenuBar
Widget 建立選單列,它定義由 macOS 而不是 Flutter 渲染的平台原生選單列。
而且,對於所有平台,您都可以定義一個 Material Design 選單,它提供階層式選單列 (MenuBar),或者由另一個使用者介面元素觸發的獨立階層式選單 (MenuAnchor)。這些選單完全可自訂,選單項目可以是自訂 Widget,或者您可以使用新的選單項目 Widget (MenuItemButton、SubmenuButton)。
Impeller 預覽
團隊很高興地宣布,新的 Impeller 渲染引擎 已在 stable channel 上的 iOS 上 準備好進行預覽。我們相信 Impeller 的效能對於大多數應用程式來說將會達到或超過 Skia 渲染器,至於保真度,Impeller 實作了所有功能,只有一些很少使用的角落案例除外。我們預計將在即將到來的穩定版本中將 Impeller 設為 iOS 上的預設渲染器,因此請在 GitHub 上繼續提交 Impeller 回饋。
儘管我們越來越有信心 iOS 上的 Impeller 將滿足幾乎所有現有 Flutter 應用程式的渲染需求,但 API 涵蓋範圍仍然存在一些差距。在 Flutter wiki 上列出了少數幾個剩餘的差距。使用者也可能會注意到 Skia 和 Impeller 之間在渲染方面的細微視覺差異。這些細微的差異可能是錯誤,因此請勿猶豫 提交議題。
社群的貢獻極大地加速了我們在 Impeller 上的進展。特別是 GitHub 使用者 ColdPaleLight、guoguo338、JsouLiang 和 magicianA 為此版本貢獻了 291 個(>12%)與 Impeller 相關的修補程式中的 37 個。謝謝!
我們繼續在 Impeller 的 Vulkan 後端上取得進展(在較舊的設備上回退到 OpenGL),但 Android 上的 Impeller 尚未準備好進行預覽。Android 支援正在積極開發中,我們希望在將來的版本中分享更多相關資訊,包括更多關於桌面和 Web 支援的資訊。
在 GitHub 上的 Impeller 專案看板 上關注我們的進展。
iOS 版本驗證
當您發佈 iOS 應用程式時,更新設定的清單 可以確保您的應用程式已準備好提交到 App Store。
flutter build ipa
命令現在會驗證其中一些設定,並在發佈之前通知您是否需要對應用程式進行更改。
DevTools 更新
在此版本中,有幾個新的工具功能和整體改進可以嘗試。DevTools 記憶體除錯工具已徹底改版。有三個新的功能標籤,剖析、追蹤 和 差異,它們支援所有以前支援的記憶體除錯功能,並為您的除錯工作添加了更多功能。新功能包括能夠按類別和記憶體類型分析應用程式目前的記憶體配置、調查在運行時哪些程式碼路徑正在為一組類別配置記憶體,以及比較記憶體快照以了解兩個時間點之間的記憶體管理。
所有這些新的記憶體功能都已記錄在 docs.flutter.dev 上,因此請查看文件以獲取更多資訊。
效能頁面也有一些值得注意的新功能。效能頁面頂部的一個新的 畫面分析 標籤提供了所選 Flutter 畫面的洞察力。洞察力可能包括如何更詳細地追蹤 Flutter 畫面中昂貴部分的建議,或者有關在 Flutter 畫面中檢測到的昂貴操作的警告。
這只是幾個亮點,但此版本包含若干錯誤修復和改進,超出此處提到的功能,包括針對 Inspector、網路分析工具和 CPU 分析工具的一些重要錯誤修復。若要更深入地了解更新列表,請查看 DevTools 變更的發行備註,這些變更已加入 Flutter 3.7。
- Flutter DevTools 2.17.0 發行備註
- Flutter DevTools 2.18.0 發行備註
- Flutter DevTools 2.19.0 發行備註
- Flutter DevTools 2.20.0 發行備註
自訂上下文選單
您現在可以在 Flutter 應用程式中的任何位置建立自訂上下文選單。您也可以使用它們自訂內建的上下文選單。
例如,您可以將「發送電子郵件」按鈕加入到使用者選取電子郵件地址時出現的預設文字選取工具列中 (程式碼)。查看 contextMenuBuilder 參數,該參數已加入預設顯示上下文選單的現有 Widget 中,例如 TextField
。您可以從 contextMenuBuilder
返回任何您想要的 Widget,包括修改預設的平台自適應上下文選單。
此新功能也適用於文字選取之外。例如,您可以建立一個 Image
Widget,當右鍵點擊或長按時顯示「儲存」按鈕 (程式碼)。使用 ContextMenuController 在應用程式中的任何位置顯示目前平台的預設上下文選單或自訂上下文選單。
在 Flutter 的樣本儲存庫 中查看完整的範例套件。
CupertinoListSection 和 CupertinoListTile Widget
感謝 Github 使用者 Campovski 的努力,Cupertino 有兩個新的 Widget:CupertinoListSection 和 CupertinoListTile,用於以 iOS 風格顯示可捲軸的 Widget 列表。它們是 Material 中 ListView
和 ListTile
的 Cupertino 版本。
捲軸改進
這個版本包含了一些 捲軸更新:針對觸控板互動的潤色和完善、新的 Widget(例如 Scrollbars
和 DraggableScrollableSheet
),以及改進了在捲軸上下文中選取文字的處理方式。
值得注意的是,MacOS 應用程式現在將會在新增 新的捲軸物理 以匹配桌面平台後,體驗到更高的保真度。
新的 AnimatedGrid 和 SliverAnimatedGrid
Widget 會為加入(或移除)列表的項目製作動畫。
最後,我們 修復了若干捲軸 Widget 的建構函數中的回歸,例如 ListView
。在 Flutter 框架的 NNBD 遷移期間,itemBuilder
(允許使用者按需提供 Widget)被遷移到 IndexedWidgetBuilder
。這意味著 itemBuilder
不再可以返回 null
,而 null
(在過去)可以用於表示已到達列表的末尾。此功能已透過 NullableIndexedWidgetBuilder
恢復。感謝 @rrousselGit 注意到這一點——遷移幾年後——並發送了修復程式!
國際化工具和文件
國際化支援已完全改版!我們已完全重寫 gen-l10n
工具,以支援:
- 描述性語法錯誤。
- 包含巢狀/多個複數、選擇和佔位符的複雜訊息。
有關更多資訊,請查看更新後的 國際化 Flutter 應用程式 頁面。
全局選取改進
SelectionArea
現在支援鍵盤選取。您可以使用鍵盤快捷鍵(例如 shift+right
)擴展現有選取範圍。
背景隔離區
現在,平台通道 可以從任何 隔離區 呼叫。以前,使用者只能從 Flutter 提供的主要隔離區呼叫平台通道。這使得在 Plugin 或 Add-to-app 中使用隔離區和主機平台程式碼變得更好。有關更多資訊,請查看 flutter.dev 上的 撰寫自訂平台特定程式碼 以及深入文章 簡介背景隔離區通道,這是一篇免費的 Medium 文章。
文字放大鏡
在 Android 和 iOS 上文字選取期間出現的放大鏡現在可以在 Flutter 中使用。這對於所有具有文字選取的應用程式來說都是開箱即用的,但如果想停用或自訂它,請查看 magnifierConfiguration 屬性。
Plugin 的 Swift 遷移
隨著 Apple 將重點放在他們自己的 API 上的 Swift,我們希望開發一些參考來幫助 Flutter Plugin 開發人員使用 Swift 遷移或建立新的 Plugin。quick_actions Plugin 已從 Objective-C 遷移到 Swift,可以用作最佳實務的演示。如果您有興趣幫助我們遷移 1P Plugin,請查看 wiki 的 Swift 遷移部分。
面向 iOS 開發人員的資源
我們為 iOS 開發人員發佈了一些新的資源,包括:
- 面向 SwiftUI 開發人員的 Flutter
- 面向 Swift 開發人員的 Dart
- 面向 Swift 開發人員的 Flutter 並發
- 將 Flutter 加入現有的 SwiftUI 應用程式
- 使用 Flutter 建立風味(適用於 Android 和 iOS)
Bitcode 棄用
從 Xcode 14 開始,watchOS 和 tvOS 應用程式不再需要 Bitcode,App Store 不再接受來自 Xcode 14 的 Bitcode 提交。 因此,Bitcode 支援已從 Flutter 中移除。
預設情況下,Flutter 應用程式沒有啟用 Bitcode,我們預計這不會影響太多開發人員。但是,如果您在 Xcode 專案中手動啟用了 Bitcode,請在升級到 Xcode 14 後立即停用它。您可以透過打開 ios/Runner.xcworkspace
並將 啟用 Bitcode 設為 否 來執行此操作。 Add-to-app 開發人員應在主機 Xcode 專案中停用它。
若要進一步了解 Bitcode 分發,請查看 Apple 的文件。
iOS PlatformView BackdropFilter
我們已添加了原生 iOS 視圖在渲染到模糊的 Flutter Widget 之下時被模糊的功能,並且 UiKitView
Widget 現在可以包裝在 BackdropFilter
中。
有關更多資訊,請查看 iOS PlatformView BackdropFilter 設計文件。
記憶體管理
此版本對記憶體管理進行了一些改進,這些改進的共同效果是減少由垃圾收集暫停造成的卡頓,降低因配置速度和背景 GC 線程造成的 CPU 使用率,以及減小記憶體佔用空間。
例如,我們擴展了現有 的手動釋放支援某些 dart:ui
Dart 物件的原生資源的做法。以前,原生資源將由 Flutter 引擎保留,直到 Dart VM 垃圾收集 Dart 物件。透過對使用者應用程式和我們自己的基準測試進行分析,我們確定這種策略通常不足以避免不合時宜的 GC 並過度使用記憶體。因此,在此版本中,Flutter 引擎添加了用於明確釋放 Vertices
、Paragraph
和 ImageShader
物件持有的原生資源的 API。
在我們對遷移到此 API 的 Flutter 框架進行基準測試時,這些改進將 90% 的畫面建立時間縮短了 30% 以上,最終使用者將體驗到更平滑的動畫,卡頓更少。
此外,Flutter 引擎 不再註冊 GPU 圖片的大小到 Dart VM。如上所述,這些圖片在不再需要時已由框架手動釋放,因此通知 Dart 的 GC 策略支援 Dart 堆物件的 GPU 記憶體大小會不必要地增加 Dart 堆記憶體壓力,從而觸發無法收集任何額外記憶體的不合時宜的 GC。基於類似的思路,Flutter 引擎現在的策略是僅向 Dart VM 報告支援 dart:ui
Dart 物件的原生物件的淺層大小。
在我們的基準測試中,此變更在建立畫面時會消除同步 GC 工作,當時 Widget 會建立 GPU 常駐圖片。
在此版本中,Flutter 引擎也更好地動態更新 Dart VM,提供有關 Flutter 應用程式狀態的資訊。特別是,Flutter 現在使用 Dart VM 的 RAIL 風格 API 在路由轉場動畫期間進入 低延遲模式。在此低延遲模式下,Dart VM 的記憶體配置器優先選擇堆增長而不是垃圾收集,以避免使用 GC 暫停中斷轉場動畫。雖然此變更沒有帶來任何顯著的效能改善,但我們計劃在將來的版本中擴展此模型的使用範圍,以進一步消除不合時宜的 GC 暫停。此外,我們已 修復了邏輯中的錯誤,這些邏輯決定何時通知 Dart VM Flutter 引擎處於空閒狀態。修復這些錯誤還可以防止 GC 相關的卡頓。最後,對於 Add-to-app Flutter 應用程式,Flutter 引擎現在會 通知 Dart VM Flutter 視圖不再顯示。這現在導致 Dart VM 為與視圖關聯的隔離區觸發最終的重大 GC。此變更在沒有 Flutter 視圖可見時會減少 Flutter 的記憶體佔用空間。
停止支援 macOS 10.11 到 10.13
如 先前宣布,Flutter 不再支援 macOS 版本 10.11 和 10.12。自那次宣布以來,進一步的分析 顯示,移除對 10.13 的支援也會產生有限的額外影響,並且將有助於團隊大幅簡化程式碼庫。這意味著使用此版本及更高版本建立的針對穩定 Flutter SDK 的應用程式將不再在這些版本上運行,並且 Flutter 支援的最低 macOS 版本將升級到 10.14 Mojave。
因此,由於 Flutter 支援的所有 iOS 和 macOS 版本都包含 Metal 支援,因此 OpenGL 後端已從 iOS 和 macOS 嵌入器中移除。移除這些後端使 Flutter 引擎的壓縮大小減少了約 100KB。
toImageSync
此版本 添加了方法 Picture.toImageSync
和 Scene.toImageSync
到 dart:ui
中,類似於異步方法 Picture.toImage
和 Scene.toImage
。Picture.toImageSync
同步返回一個 Image
的句柄,其中 Image
的光柵化會在背景中異步執行。然後,當 GPU 上下文可用時,圖片會保留為 GPU 常駐,這意味著與透過 toImage
生成的圖片相比,它的繪製速度更快。(透過 toImage
生成的圖片也可以保留為 GPU 常駐,但這種優化尚未在這種情況下實作。)
新的 toImageSync
API 支援以下用例:
- 迅速捕捉一個光柵化代價高昂的圖片,以便在多個畫面中重複使用。
- 將多通道濾鏡應用於圖片。
- 應用自訂著色器。
例如,Flutter 框架現在 使用此 API 來改進 Android 上的頁面轉場效能,這幾乎將畫面光柵化時間減半,減少了卡頓,並允許動畫在支援這些更新率的設備上達到 90/120fps。
自訂著色器支援改進
此版本包含 Flutter 對自訂片段著色器支援的許多改進。Flutter SDK 現在包含一個著色器編譯器,它會將 pubspec.yaml
檔案中列出的 GLSL 著色器編譯為目標平台的正確後端特定格式。此外,自訂著色器現在可以熱重新載入,以實現便捷的開發週期。自訂著色器現在也受 iOS 上的 Skia 和 Impeller 後端支援。
我們對社群已經分享的演示非常印象深刻,並且期待看到自訂著色器在 Flutter 中的進一步創新使用:
- https://twitter.com/reNotANumber/status/1599717360096620544
- https://twitter.com/reNotANumber/status/1599810391625719810
- https://twitter.com/wolfenrain/status/1600242975937687553
- https://twitter.com/iamjideguru/status/1598308434608283650
- https://twitter.com/rxlabz/status/1609975128758026247
- https://twitter.com/RealDevOwl/status/1528357506795421698
- https://twitter.com/TakRutvik/status/1601380047599808513
- https://twitter.com/wolfenrain/status/1600601043477401606
在 docs.flutter.dev 上查看 撰寫和使用自訂片段著色器 的詳細文件,並查看 pub.dev 上的實用程式套件 flutter_shaders。
字體資產熱重新載入
以前,將新字體添加到 pubspec.yaml
檔案中需要重新建立應用程式才能看到它們,這與可以熱重新載入的其他資產類型不同。現在,對字體清單的更改(包括新增新字體)可以在應用程式中熱重新載入。
減少 iOS 設備上的動畫卡頓
感謝 luckysmg 的開源貢獻,兩個改進減少了 iOS 上的動畫卡頓。特別是,在手勢期間在主線程上添加一個虛擬 CADisplayLink
現在會強制以最大更新率刷新。此外,鍵盤動畫 現在會將 CADisplayLink
的更新率設定為與 Flutter 引擎的動畫器使用的相同更新率。由於這些更改,使用者應該會注意到 120Hz iOS 設備上更一致的平滑動畫。
總結
毫不誇張地說,沒有才華橫溢且充滿熱情的貢獻者社群,Flutter 就無法成為今天的傑出體驗。我們將繼續一起踏上這段旅程,Google 的 Flutter 團隊希望大家知道,沒有你們,我們是無法做到的。謝謝!
這股勢頭不會減弱,敬請關注未來的更新!
Flutter 3.7 的新功能 最初發佈在 Flutter 上的 Medium,人們在那裡透過突出顯示和回應這個故事來繼續討論。