Flutter 1.22 正式發佈

支持iOS 14和Android 11,新的i18n和l10n支持,可用於生產的Google Maps和WebView插件,新的App Size工具等等!linux

做者:Chris Sellsandroid

原文:https://medium.com/flutter/announcing-flutter-1-22-44f146009e5fios

咱們很高興推出最新版本的Flutter,它普遍支持iOS 14和Android11。Flutter 1.22在之前版本的基礎上構建,使開發人員可以從一個代碼庫爲多個平臺構建快速,美觀的用戶體驗。咱們的季度穩定版本包含最新功能,性能改進和錯誤修復,適合普遍的生產使用。git

因爲這是新的移動操做系統版本的發佈季節,所以此發行版側重於確保Android 11和iOS 14與Flutter兼容。這兩個操做系統的更新都包括大量的幕後工做,以符合最新的SDK並確保全部內容都經過咱們普遍的測試套件。對於iOS 14,此版本包括對新Xcode 12,新圖標的支持以及對新iOS 14 App Clips功能的預覽支持。對於Android 11,此更新支持新類型的顯示切口以及在調出軟鍵盤時更流暢的動畫。github

該版本發佈於咱們的1.20發佈兩個月以後,所以比大多數版本都短。即便在這麼短的時間內,咱們也關閉了3,024期,合併了197個貢獻者的1,944個PR。在這些貢獻者中,有114位(58%)來自整個社區,他們貢獻了271個PR。最大的單一貢獻者是 a14n,他再次以20個PR成爲咱們的傑出貢獻者名單,其中大多數是做爲支持Flutter中的零安全性工做的一部分而完成的(更多內容即將推出)。web

除了對新的移動操做系統版本的支持外,還有不少其餘要分享的新聞,包括預覽Android最重要的功能之一:狀態恢復,新的「Material 風格按鈕「,新的國際化和本地化支持(與熱重載一塊兒使用),一個新的Navigator,一個穩定的Platform Views版本(Google Maps和WebView插件的基礎)以及一個開關,您能夠在其中添加代碼以改善在具備高頻率顯示的設備上的滾動。咱們還提供了一個用於剖析應用程序大小並確保您要構建的插件僅支持您要支持的平臺的新工具。macos

iOS 14

每當發佈新版本的移動操做系統時,咱們都會對其進行完全測試,以查找影響Flutter及其工具的不兼容性或更改。windows

對於iOS 14,咱們對Flutter進行了不少更改,以確保它能夠按照開發人員的方式工做:visual-studio-code

  • 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用戶得到最佳體驗。api

有關使用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視圖上。

若是您之前在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擴展的最新版本中,如今能夠正確解析這些連接,以使您能夠直接從輸出中啓用連接。

看來這是一件小事,可是對於此功能的初步反饋已經很是積極。

與往常同樣,此處的工具更改列表太多,可是我建議如下公告以瞭解詳細信息:

客戶關注點:EasyA

EasyA是一款訂閱應用程序,旨在使適齡學生經過即時消息與出色的導師聯繫,並使用Flutter編寫。最近,它被Apple推薦爲「每日應用程序」。

「當學校在今年初開始上網時,咱們知道咱們須要快速啓動輔導應用程序來幫助學生。 Flutter的驚人發展速度意味着咱們可以爲iOS和Android實施屢獲殊榮的設計,而且還能夠發佈到Web上—及時鎖定!一般,這其實是不可能的。可是,因爲Flutter容許咱們同時針對全部三個平臺,所以咱們可以高效地共享代碼,並充分利用咱們的小型開發人員團隊。」

EasyA聯合創始人Phil Kwok

重大變化

與往常同樣,咱們試圖將重大更改的數量保持在最少。如下是Flutter 1.22版本中的列表。

概要

Flutter 1.22穩定版可能在上一版本以後很快問世,可是其中包含不少好東西,所以本篇文章沒法一一列舉。咱們但願此版本能夠幫助您爲iOS和Android開發出色的應用程序,咱們火燒眉毛想看到您的商店中有什麼!感謝您的支持-咱們爲您打造Flutter。

交流

老孟Flutter博客(330個控件用法+實戰入門系列文章):http://laomengit.com

歡迎加入Flutter交流羣(微信:laomengit)、關注公衆號【老孟Flutter】:

相關文章
相關標籤/搜索