Flutter 1.22 正式發佈
支持iOS 14和Android 11,新的i18n和l10n支持,可用於生產的Google Maps和WebView插件,新的App Size工具等等!
作者:Chris Sells
原文://medium.com/flutter/announcing-flutter-1-22-44f146009e5f
我們很高興推出最新版本的Flutter,它廣泛支持iOS 14和Android11。Flutter 1.22在以前版本的基礎上構建,使開發人員能夠從一個代碼庫為多個平台構建快速,美觀的用戶體驗。我們的季度穩定版本包含最新功能,性能改進和錯誤修復,適合廣泛的生產使用。
由於這是新的移動操作系統版本的發佈季節,因此此發行版側重於確保Android 11和iOS 14與Flutter兼容。這兩個操作系統的更新都包括大量的幕後工作,以符合最新的SDK並確保所有內容都通過我們廣泛的測試套件。對於iOS 14,此版本包括對新Xcode 12,新圖標的支持以及對新iOS 14 App Clips功能的預覽支持。對於Android 11,此更新支持新類型的顯示切口以及在調出軟鍵盤時更流暢的動畫。
該版本發佈於我們的1.20發佈兩個月之後,因此比大多數版本都短。即使在這麼短的時間內,我們也關閉了3,024期,合併了197個貢獻者的1,944個PR。在這些貢獻者中,有114位(58%)來自整個社區,他們貢獻了271個PR。最大的單一貢獻者是 a14n,他再次以20個PR成為我們的傑出貢獻者名單,其中大多數是作為支持Flutter中的零安全性工作的一部分而完成的(更多內容即將推出)。
除了對新的移動操作系統版本的支持外,還有很多其他要分享的新聞,包括預覽Android最重要的功能之一:狀態恢復,新的「Material 風格按鈕「,新的國際化和本地化支持(與熱重載一起使用),一個新的Navigator,一個穩定的Platform Views版本(Google Maps和WebView插件的基礎)以及一個開關,您可以在其中添加代碼以改善在具有高頻率顯示的設備上的滾動。我們還提供了一個用於剖析應用程序大小並確保您要構建的插件僅支持您要支持的平台的新工具。
iOS 14
每當發佈新版本的移動操作系統時,我們都會對其進行徹底測試,以查找影響Flutter及其工具的不兼容性或更改。
對於iOS 14,我們對Flutter進行了很多更改,以確保它可以按照開發人員的方式工作:
- Xcode 12需要iOS 9.0或更高版本,因此我們的默認模板將其默認值從8.0增加到9.0
- iOS 14特定崩潰和字體渲染問題已在Flutter 1.22中修復
- Flutter 1.20.4,修復了部署到真機設備的問題
- 當應用程序訪問其剪貼板時顯示使用通知,導致在Flutter應用程序中出現虛假通知,該問題已在Flutter 1.20.4中修復
- iOS 14設備上會禁止運行debug應用程序,但實際開發debug除外
- 針對本地調試的Flutter應用程序的有關網絡安全的新策略使iOS 14顯示一次性確認對話框(僅在開發過程中,不適用於已發佈的Flutter應用程序)
如果您要通過Flutter應用定位iOS 14,我們強烈建議您使用Flutter 1.22對其進行重建,然後立即將其部署到App Store中,以確保您的iOS 14用戶獲得最佳體驗。
有關使用Flutter適配iOS 14的更多詳細信息,包括添加Flutter應用到原生應用,deep linking和通知注意事項,請參閱 flutter.dev上的iOS 14文檔。
希望所有有關工具和SDK支持的工作都可以讓您專註於自己關心的編碼-利用iOS 14的新功能。
其中一項功能是對iOS的新SF Symbols字體的更新支持,我們花一些時間更新了cupertino_icon程序包。將cupertino_icons依賴關係更新為新的1.0主要版本後,CupertinoIcons的現有用法將自動映射到新樣式。如果您將cupertino_icons 1.0與Flutter 1.22結合使用,那麼您還可以通過CupertinoIcons API訪問約900個新圖標。
您可以在cupertino_icons預覽頁面上看到圖標的完整列表,在 flutter.dev上可以看到遷移詳細信息頁面。
您可以在iOS 14上嘗試使用Flutter的另一個功能是App Clips,它是iOS 14的一項新功能,它支持10MB以下輕量級應用程序的快速,無安裝應用程序執行。在Flutter 1.22版中,我們預覽了使用Flutter構建的App Clip目標。
有關如何使用Flutter構建Clip的更多詳細信息,請查看flutter.dev上的文檔。您也可以參考這個簡單的示例項目。
Android 11
Flutter的這個版本也與本月Android 11的發佈相吻合。 Flutter框架和引擎已更新,以支持最新版本的Android中引入的兩個新功能。
首先,Flutter現在支持多種屏幕適配(比如瀑布屏)。
通過使用MediaQuery和SafeArea API,您可以確保將活動的UI和交互式元素放置在設備顯示屏的無障礙區域中。另外,您將要避免在瀑布邊緣區域使用手勢檢測器,因為這可能會導致意外觸摸。
其次,動畫在顯示軟件鍵盤時與Android 11同步。
問題 #19279是一個長期存在的問題,其中系統鍵盤的顯示/隱藏動畫與Flutter的插圖不同步。這在Android 11中已修復。
關於Android嵌入API的一項說明。去年,隨着Flutter 1.12版的推出,我們推出了一套適用於Android的新Flutter引擎和Flutter插件API。我們創建了這些v2 API,以更好地支持Android上的應用程序添加用戶。一年後,超過80%的Android插件使用了新的Android API。從1.22開始,我們不再使用較舊的v1 API。
如果您仍在使用Android v1 API,那麼這對您意味着:
- 新創建的插件將不再針對v1 API
- Flutter工具的
-no-enable-android-embedding-v2
配置標記已刪除,現在是默認行為 - 仍在使用v1 API的舊版應用程序在構建過程中將顯示棄用警告,該警告指向支持新的Android插件API文檔
同時,如果您仍然有基於v1 Android API的Flutter應用程序,它將繼續運行。但是,您可能會開始遇到僅針對v2 API且v1 Android API無法使用的新插件。有關更多詳細信息,請參見重大更改文檔。
擴展的 Button 組件
現有的Flutter按鈕看上去不錯,但很難使用,尤其是在需要自定義主題時。此外,「Material」規範已擴展為包括具有新樣式的新按鈕。
為使Flutter保持與Material指南的最新水平,我們很高興地宣布Flutter 1.22中的引入全新的按鈕。
該PR並沒有嘗試就地開發現有的按鈕類及其主題,而是引入了新的替換按鈕小部件和主題。除了使我們擺脫現有類的向後兼容性迷宮之外,新名稱還使Flutter與Material Design規範同步,後者使用按鈕組件的新名稱。
新主題遵循Flutter最近在新Material窗口小部件中採用的「規範化」模式。如果您想玩演示,DartPad上有一個很棒的演示。這並不是一個重大變化,因為FlatButton,OutlineButton,RaisedButton,ButtonBar,ButtonBarTheme和ButtonTheme的語義不會改變。您可以將舊按鈕與新按鈕混合使用。
新的國際化和本地化支持
自Flutter創立以來,Flutter已提供您的應用程序國際化(i18n)和本地化(l10n)所需的核心功能。但是,在此版本中,我們將最佳做法的意見納入了我們的工具中,甚至在添加新的l10n信息時啟用了熱重裝支持來更新您的應用。
如果您想了解有關Flutter對l10n的支持的更多詳細信息,包括本地化消息,帶有參數的消息,日期,數字和貨幣,請閱讀Flutter Internationalization用戶指南。
此外,如果您對i18n和l10n感興趣,那麼您可能還對那些字符串不適合普通ASCII字符的字符串感興趣,例如Unicode和emoji。最近,Dart團隊發佈了character軟件包,該軟件包可幫助開發人員處理Unicode(擴展)字形簇。該軟件包有助於解決諸如如何正確地將字符串(如「 A in text in English」)縮寫為前15個字符的問題。使用String類,該縮寫為「 A🇬🇧text in」,它僅是12個用戶可感知的字符。另一方面,使用字符包會產生「 A🇬🇧text in Eng」的正確縮寫。
通過此PR,Flutter使用字符包來正確處理這些複雜字符。例如,當使用具有maxLength限制的TextField時,像👨👩👦這樣的字符現在可以正確地計為單個字符。同樣,有了此PR,在Flutter所在的項目中,字符包均可自動在項目中使用,而無需手動添加。希望這使得處理來自所有語言環境的各種字符串變得更加容易。有關character包的更多詳細信息,請查看出色的文章,正確完成Dart字符串操作。
Google Maps和WebView插件準備投入生產
在Flutter小組的這裡,我們通常會謹慎地將某些標籤標記為「生產就緒」,直到我們對自己進行徹底測試為止。對於google_maps_flutter和webview_flutter插件,選通因素一直是底層的Platform Views實現,該實現允許將Android和iOS的本機UI組件託管在Flutter應用程序中。在此版本的Flutter中,我們很高興地宣布,我們對框架進行了強化,足以將這兩個插件聲明為可以投入生產。
在Flutter 1.22中,我們添加了替代的Platform Views實現,該實現修復了所有已知的鍵盤以及Android視圖的可訪問性問題。此外,它還適用於19級及以上的Android API(以前要求20級)。我們還在iOS上進行了線程改進,使平台視圖更高效,更可靠(並且不再需要您將io.flutter.embedded_views_preview標誌添加到iOS Info.plist)。
webview_flutter插件支持新的Android平台視圖模式,但當前需要手動啟用。一旦在更廣泛的社區中得到更多使用,我們將默認在將來的版本中啟用它。
Google Maps和WebView插件已經從Platform Views的改進中受益。如果您想使用平台視圖在iOS或Android上託管自己的本機UI組件,則可以了解如何在使用平台視圖在Flutter應用中託管本機Android和iOS視圖上。
Navigator 2.0
如果您以前在Flutter應用程序中使用過導航功能,則可能已經注意到核心數據結構(用戶正在瀏覽的頁面堆棧)對您而言是隱藏的。而是要對其進行管理,請調用Navigator.pop()或Navigator.push()。舉例來說,假設您想在首頁上顯示一系列小部件,並允許用戶點擊一個小部件以轉到專門針對該顏色的詳細信息頁面。
實現如下:
class ColorListScreen extends StatelessWidget {
final List<Color> colors;
final void Function(Color color) onTapped;
ColorListScreen({this.colors, this.onTapped});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text('Colors')),
body: Column(
children: [
// you can see and decide on every color in this list
for (final color in colors)
Expanded(
child: GestureDetector(
child: Container(color: color),
onTap: () => onTapped(color),
),
)
],
),
);
}
class ColorScreen extends StatelessWidget {
final Color color;
const ColorScreen({this.color});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: Text('Color')),
body: Container(color: color),
);
}
使用最簡單的Navigator 1.0樣式,您可以以看起來非常簡單的方式在這兩個屏幕之間導航:
class _ColorAppState extends State<ColorApp> {
List<Color> _colors = [Colors.red, Colors.green, Colors.blue];
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Color App',
home: Builder(
builder: (context) => ColorListScreen(
colors: _colors,
// the Navigator manages the list of pages itself; you can only push and pop
onTapped: (color) => Navigator.push(
context,
MaterialPageRoute(builder: (context) => ColorScreen(color: color)),
),
),
),
);
}
只需對Navigator.push()進行調用,即可將第一個頁面推到第一個頁面的頂部,從而創建兩頁的堆棧。但是,與在ColorListScreen的build方法中創建的Container列表不同,該堆棧對您隱藏。而且,由於它是隱藏的,因此很難針對其他情況進行管理,例如處理由本機嵌入提供的初始路由的深層鏈接,或者來自Web的URL或來自Android的意圖。管理同一頁面的不同排列之間的嵌套路由也極其困難。
Navigator 2.0通過使頁面堆棧可見而解決了這些問題,甚至更多。這是在相同的ColorListScreen和ColorScreen之間導航的更新示例:
class _ColorAppState extends State<ColorApp> {
Color _selectedColor;
List<Color> _colors = [Colors.red, Colors.green, Colors.blue];
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Color App',
home: Navigator(
// you can see and decide on every page in this list
pages: [
MaterialPage(
child: ColorListScreen(
colors: _colors,
onTapped: (color) => setState(() => _selectedColor = color),
),
),
if (_selectedColor != null) MaterialPage(child: ColorScreen(color: _selectedColor)),
],
onPopPage: (route, result) {
if (!route.didPop(result)) return false;
setState(() => _selectedColor = null);
return true;
},
),
);
}
該應用程序顯式創建一個導航器,並為其提供代表完整堆棧的頁面列表。我們創建一個空的_selectedColor,以指示尚未選擇任何顏色,因此我們最初不顯示ColorScreen。當用戶選擇一種顏色時,我們通常會調用setState()來向Flutter表示您希望再次調用build()方法,該方法現在會創建一個堆棧,其頂部是ColorScreen。
您可以在OnPopPage回調中更新狀態,例如,如果用戶彈出,則表示他們已「取消選擇」當前顏色,因此我們不再希望顯示該頁面。
如果Navigator 2.0看起來像Flutter的其餘部分,那就是意圖-它是聲明性的,而Navigator 1.0則是必須的。這個想法是要在導航和Flutter的其餘部分之間統一模型,同時解決許多問題並添加功能。實際上,這個小例子幾乎不涉及Navigator 2.0的內容。有關詳細信息,我強烈推薦有關Flutter中的聲明式導航和路由的文章。
另外,您對Navigator 1.0的現有使用將像今天一樣繼續使用,並且不會在短期內被刪除。如果您喜歡該模型,則可以繼續使用它。但是,如果您嘗試使用Navigator 2.0,我們認為您會喜歡的。
預覽:Android的狀態還原
在此版本中可供您試用的新功能是對Android狀態恢復的支持。這是我們最受歡迎的功能之一,擁有217個大拇指!
對於不熟悉狀態還原需求的用戶,移動操作系統可能會殺死後台的應用程序,以回收前台應用程序的資源。發生這種情況時,操作系統會通知該應用被終止以快速保存任何UI狀態,以便在用戶循環回到該應用時可以將其恢復。正確實施後,可以為用戶提供無縫的體驗,同時可以更好地利用設備的資源。到目前為止,Flutter不支持狀態還原,沒有框架的支持,很難正確地進行狀態還原。因此,我們很高興能夠為Android提供此功能的基本實現。
這是一個用於恢復默認Flutter Counter應用狀態的非常簡單的示例:
class CounterState extends State<RestorableCounter> with RestorationMixin {
@override
String get restorationId => widget.restorationId;
RestorableInt _counter = RestorableInt(0);
@override
void restoreState(RestorationBucket oldBucket) => registerForRestoration(_counter, 'count');
void _incrementCounter() => setState(() => _counter.value++);
@override
Widget build(BuildContext context) => Scaffold(
body: Center(child: Text('${_counter.value}')),
floatingActionButton: FloatingActionButton(onPressed: _incrementCounter),
);
}
簡要地說,每個小部件都有一個 storage bucket,該storage bucket使用唯一的ID向RestorationMixin註冊。通過使用RestorableProperty類型(如此處使用的RestorableInt)來存儲特定於UI的數據,並通過State Restoration功能註冊該數據,該數據將在Android殺死該應用之前自動存儲,並在其恢復正常運行時恢復。就是這樣。所有以Restoration *類型存儲的數據,例如RestorableInt,RestoableString和RestorableTextEditingController(我們都有很多)都將被還原。而且,如果我們沒有涵蓋您要還原的所有類型,則可以通過擴展RestorableProperty創建自己的類型。
為了自動測試狀態恢復,我們向WidgetTester添加了新的restartAndRestore API。要進行手動測試,最簡單的方法是在Android設備上啟動啟用了狀態恢復功能的Flutter應用,在Android開發人員設置中啟用「不要保留活動」,運行Flutter應用,將其置於後台,然後然後回到它。此時,Android將終止並恢復您的應用程序,因此您可以查看一切是否按預期工作。
儘管我們很高興將狀態恢復的預覽版放在您的手中,但還有更多工作要做。例如,狀態恢復不僅適用於Android,iOS應用程序也可以受益。此外,我們正在忙於更新自己的窗口小部件,以在恢復過程中保持其狀態。我們已經在Scrollable類中提供了支持,例如ListView和SingleChildScrollView(記住用戶的滾動位置)和TextField(恢復他們輸入的文本),並且我們計劃將其擴展到其他小部件。
預覽:平滑滾動以提供不匹配的輸入和顯示頻率
當輸入和顯示頻率不同時,Flutter團隊與Google內部合作夥伴合作,極大地提高了滾動性能。例如,Pixel 4輸入的運行頻率為120hz,而顯示屏的運行頻率為90hz。滾動時,這種不匹配會導致性能下降。使用新的resamplingEnabled標誌,您可以利用我們在Flutter中完成的性能工作來解決此問題:
void main() {
GestureBinding.instance.resamplingEnabled = true;
run(MyApp());
}
根據所涉及的頻率差異,啟用此標誌可以使滾動時的顫動減少多達97%。當我們確定這是最好的體驗時,我們計劃在以後的版本中默認啟用此標誌。
新的統一的Dart開發人員工具
與往常一樣,對Flutter的更新不僅意味着引擎和框架,還包括工具。 Flutter 1.22包括Dart(2.10)的新版本,還有一個新的dart CLI工具,您可能也會發現它有用。
Dart歷史上有許多較小的開發人員工具(例如,用于格式化的dartfmt和用於代碼分析的dartanalyzer)。 Dart 2.10中的新增功能是一個與Flutter工具非常相似的統一的Dart開發人員工具。
從今天的Flutter 1.22 SDK開始,您會發現/ bin文件夾(您可能在PATH中包含該文件夾)同時包含flutter和dart命令。有關更多詳細信息,請參見Dart 2.10博客文章。
應用程式大小分析工具
作為Flutter 1.22的一部分發佈的工具包括一個新的輸出大小分析實用程序。此工具可幫助診斷Flutter,您的應用大小細分是否會隨着時間變化。
您可以通過將–analyze-size標誌傳遞給以下任何命令來使用該工具收集分析所需的數據:
flutter build apk
flutter build appbundle
flutter build ios
flutter build linux
flutter build macos
flutter build windows
在構建Flutter輸出工件時使用此標誌將打印工件尺寸和組成的摘要。這包括本機代碼,資產,甚至是已編譯Dart代碼的程序包級細分。
此摘要有助於快速識別應用程序的程序包大小用法中的熱點。此外,收集到的數據還可以作為JSON文件使用,供Dart DevTools使用,它使您可以按照flutter.dev上的說明進一步瀏覽應用程序的內容,查明大小問題並查看兩個不同JSON文件之間的更改。加載JSON文件後,您將擁有一個界面,該界面為您提供應用大小的樹狀圖。
有關您可以使用「應用大小」工具執行的操作的更多詳細信息,請閱讀flutter.dev上的「使用應用大小工具」文檔。
預覽:DevTools中更新的網絡頁面
此版本中的另一個DevTools預覽功能是能夠在「網絡」選項卡中查看HTTP和HTTPs響應主體。
要啟用此功能,請通過flutter通道dev和flutter通道升級確保您位於Flutter dev通道上。
此外,對於具有大量網絡流量的應用,我們提供了搜索和過濾功能。
有關「網絡」選項卡的文檔,請參閱在flutter.dev上使用網絡視圖。
IntelliJ中的託管DevTools檢查器選項卡
一段時間以來,我們一直在維護某些Flutter工具的兩個副本,例如IntelliJ中的Inspector窗格和Dart DevTools中的Inspector選項卡。這不僅會減慢我們的速度,因為我們必須維護兩個代碼庫,而且某些功能尚未納入IntelliJ插件中,例如布局資源管理器。因此,為了解決這兩個問題,我們啟用了直接從IntelliJ內部的Dart DevTools託管「檢查器」選項卡的功能。
注意添加了Layout Explorer,您可以在代碼旁邊使用它。要啟用此選項,請轉至 Preferences > Languages & Frameworks > Flutter > Enable embedded DevTools inspector
改進了Visual Studio Code中的輸出鏈接
Flutter開發人員所面臨的常規活動是從終端或堆棧跟蹤中的錯誤輸出中進行。在適用於Visual Studio Code的Flutter擴展的最新版本中,現在可以正確解析這些鏈接,以使您可以直接從輸出中啟用鏈接。
看來這是一件小事,但是對於此功能的初步反饋已經非常積極。
與往常一樣,此處的工具更改列表太多,但是我建議以下公告以了解詳細信息:
- Dart DevTools — 0.9.0
- Dart DevTools — 0.9.1
- Dart DevTools — 0.9.3
- Flutter IntelliJ Plugin M48.1 Release
- Flutter IntelliJ Plugin M49 Release
- Flutter IntelliJ Plugin M50 Release
- VS Code extensions v3.14.0
- VS Code extensions v3.15.0
客戶關注點:EasyA
EasyA是一款訂閱應用程序,旨在使適齡學生通過即時消息與出色的導師聯繫,並使用Flutter編寫。最近,它被Apple推薦為「每日應用程序」。
「當學校在今年初開始上網時,我們知道我們需要快速啟動輔導應用程序來幫助學生。 Flutter的驚人發展速度意味着我們能夠為iOS和Android實施屢獲殊榮的設計,並且還可以發佈到Web上—及時鎖定!通常,這實際上是不可能的。但是,由於Flutter允許我們同時針對所有三個平台,因此我們能夠高效地共享代碼,並充分利用我們的小型開發人員團隊。」
EasyA聯合創始人Phil Kwok
重大變化
與往常一樣,我們試圖將重大更改的數量保持在最少。以下是Flutter 1.22版本中的列表。
- 56413 Prevent viewport.showOnScreen from scrolling the viewport if the specified Rect is already visible.
- 62395 [gen_l10n] Synthetic package generation by default
- 62588 Build routes even less.
概要
Flutter 1.22穩定版可能在上一版本之後很快問世,但是其中包含很多好東西,因此本篇文章無法一一列舉。我們希望此版本可以幫助您為iOS和Android開發出色的應用程序,我們迫不及待想看到您的商店中有什麼!感謝您的支持-我們為您打造Flutter。
交流
老孟Flutter博客(330個控件用法+實戰入門系列文章)://laomengit.com
歡迎加入Flutter交流群(微信:laomengit)、關注公眾號【老孟Flutter】:
![]() |
![]() |