By Chris Sells

Translator: heqingbao

Original text: medium.com/flutter/ann…

It takes about 17 minutes to read this article

On October 1, Google released Version 1.22 of Flutter, which supports iOS 14 and Android 11. New i18N and L10N support can be used to produce Google Maps and WebView plug-ins for projects. New App Size tools and more.

We are pleased to note that the latest version of Flutter provides extensive support for iOS 14 and Android 11. Build on previous versions, Flutter 1.22 enables developers to build a fast and aesthetically pleasing user experience for multiple platforms from a single code base. Our quarterly stable release contains the latest features, performance improvements and bug fixes for use in a wide range of production environments.

Since this is the release season for the new mobile operating system version, this release focuses on ensuring that Android 11 and iOS 14 are compatible with Flutter. Both OS updates involve a lot of behind-the-scenes work to get up to date with the latest SDK and make sure everything goes through our extensive test suite. For iOS 14, this release includes support for the new Xcode 12, new ICONS and preview support for the new iOS 14 App Clips feature. For Android 11, this update supports new types of display notches and smoother animations when bringing up the soft keyboard.

This release comes two months after our 1.20 release and is therefore shorter than most. Even in that short time, we closed 3,024 issues and consolidated 1,944 PR from 197 contributors. Of these contributors, 114 (58%) came from the community as a whole, contributing 271 PR. The largest single contributor was A14N, which again made our best contributor list with 20 PR’s, most of which were done as part of the work supporting zero security in Flutter (more coming soon).

In addition to support for new versions of the mobile operating system, there’s plenty of other news to share, including a preview of one of Android’s most important features: State restoration, new Material button “Universe”, new internationalization and localization support (used with hot reloading), a new Navigator, a stable version of the Platform Views (Google Maps and WebView) Plug-in base) and a switch where you can add code to improve scrolling on devices with high frequency displays. We have also provided a new tool for profiling application sizes and ensuring that plug-ins built only support the platform to be supported.

Support iOS 14

Whenever a new version of the mobile operating system is released, we thoroughly test it to find incompatibilities or changes affecting Flutter and its tools.

For iOS 14, we made a number of changes to Flutter to ensure that it works the way developers do:

  • Xcode 12 requires iOS 9.0 or later, so our default template increases its default value from 8.0 to 9.0
  • IOS 14 specific crashes and font rendering issues have been fixed in Flutter 1.22
  • Deployment to physical devices has been resolved since Flutter 1.20.4
  • A new policy that displays use notifications when an application accesses its clipboard, resulting in bogus notifications in a Flutter application, has been fixed in Flutter 1.20.4
  • The restriction prevents debugging applications from running on iOS 14 devices, except as part of the debugging process
  • New policy on network security for locally debugged Flutter applications causes iOS 14 to display a one-time confirmation dialog (only during development, not for published Flutter applications)

The Bottom line: If your Flutter application is for iOS 14, we strongly recommend that you rebuild it with Flutter 1.22 and deploy it to the App Store immediately to ensure the best experience for your iOS 14 users.

For more details on using Flutter to locate iOS 14, including some “Add to app”, deep links and notification considerations, see the iOS 14 documentation on Flutter. Dev.

Hopefully all the work on the tools and SDK support will allow you to focus on the coding you care about – taking advantage of the new features in iOS 14.

One such feature is the updated support for the new SF Symbols font for iOS, which inspired us to spend some time working on itcupertino_icon packageRefresh. Cupertino_icons Once the Cupertino_icons dependencies are updated to the new 1.0 major version, existing uses are automatically mapped to the new style. If you combine Cupertino_icons 1.0 with Flutter 1.22, you can passCupertinoIconsAPI access to about 900 new ICONS.You can be incupertino_iconsSee the full list of ICONS on the preview page, available on flutter. DevMigrate the details page.

Another feature you can try with Flutter on iOS 14 is thisApp Clips”, a new feature in iOS 14 that enables fast, no-install application execution for lightweight applications under 10MB. In The Release of Flutter 1.22, we preview the App Clip target built with Flutter. A Flutter-powered App Clip experience

For more details on how to build application clips using Flutter, see the documentation on Flutter. Dev. You can also refer to this simple sample project.

Support Android 11

This version of Flutter also coincides with the release of Android 11 this month. The Flutter framework and engine have been updated to support two new features introduced in the latest version of Android.

First, Flutter supports Android notches, notches, and waterfalls.Through the use ofMediaQuery 和 SafeAreaAPI, you can ensure that active UI and interactive elements are placed in a barrier-free area of the device’s display. In addition, you will want to avoid using gesture detectors at the edge of the waterfall, as this can lead to accidental touching.

Second, the animation syncs with Android 11 when displaying the software keyboard. Issue # 19279Is a long-standing issue where the show/hide animation of the system keyboard is not synchronized with the Flutter illustrations. This has been fixed in Android 11.

A note about the Android embedded API. Last year, with the release of Version 1.12 of Flutter, we introduced a new Flutter engine and THE Flutter plugin API for Android. We created these V2 apis to better support adding users to applications on Android. A year later, more than 80% of Android plug-ins use the new Android API. As of 1.22, we no longer use the older V1 API.

If you’re still using the Android V1 API, what this means for you:

  • The newly created plug-in will no longer target the V1 API
  • The -no-enable-android-embedding- v2Config flag of the Flutter tool has been removed and is now the default behavior
  • Older applications that still use the V1 API will display deprecation warnings during the build process that point to documentation supporting the new Android plug-in API

Meanwhile, if you still have the Flutter application based on the V1 Android API, it will continue to run. However, you may start to encounter new plug-ins for the V2 API only that cannot be used by the V1 Android API. See the Significant Change documentation for more details.

Expanding the Button “Universe”

The existing flutter button looks good, but can be difficult to use, especially if you need to customize the theme. In addition, the Material specification has been extended to include new buttons with new styles.

To keep Flutter up to date with the Material guide, we are pleased to announce the new “universe” for the buttons in Flutter 1.22.

The PRInstead of trying to develop existing button classes and themes in place, new alternative button widgets and themes are introduced. In addition to freeing us from the backward compatibility maze of existing classes, the new name also makes Flutter compatible withThe Material Design specificationSynchronization, which uses the new name of the button component. A new universe of Material Design buttons The new theme follows the “normalized” pattern that Flutter recently adopted in the new Material widget. If you want to play the demo,There’s a great demo on DartPad. This is not due to significant semantic changes to FlatButton, OutlineButton, RaisedButton, ButtonBar, ButtonBarTheme, and ButtonTheme will not change. You can mix old buttons with new ones as you like.

New internationalization and localization support

Since Its inception, Flutter has provided the core functionality needed to internationalize (I18N) and localize (L10N) your application. In this release, however, we incorporate best practice advice into our tools and even enable hot reload support to update your application when adding new L10N information.For more detailed information about Flutter support for L10N, including localized messages, messages with parameters, dates, numbers, and currencies, please readGuide to Flutter Internationalization.

Also, if you’re interested in i18N and L10N, you might be interested in strings that don’t fit into plain old ASCII, such as Unicode and emoji. The Dart team recently released the Characters Package, which helps developers work with Unicode (extended) glyphs. The package helps solve problems such as how to properly abbreviate strings (such as “A 🇬🇧 text in English”) to the first 15 characters. With the String class, which is abbreviated to “A 🇬🇧 text in”, it is just 12 user-aware characters. On the other hand, using the characters package produces the correct abbreviation for “A 🇬🇧 text in Eng”.

With this PR, Flutter uses character packs to properly handle these complex characters. For example, characters like 👨👩👦 can now correctly count as a single character when using TextField with a maxLength limit. Similarly, using this PR, character packs are automatically used in projects that Flutter is in, without manual addition. Hopefully, this makes it easier to work with various strings from all locales. For more details on the Character package, check out the excellent article on properly completing the Dart string manipulation at 👉.

Google Maps and the WebView plug-in are ready

On the Flutter team, we are usually careful to label certain labels as “production ready” until we have thoroughly tested ourselves. For google_maps_FLUTTER and webview_FLUTTER plug-ins, the gating factor has always been the underlying Platform Views implementation, This implementation allows native UI components of Android and iOS to be hosted in Flutter applications. In this Version of Flutter, we are pleased to announce that we have strengthened the framework enough to declare both plug-ins ready for production.

webview_flutter plugin hosting flutter.dev

In Flutter 1.22, we added an alternative Platform Views implementation that fixes all known keyboard and Android view accessibility issues. It also works with Android apis at level 19 and above (previously required level 20). We’ve also implemented threading improvements on iOS to make platform views more efficient and reliable (and eliminate the need for you to add the IO. Flutter. Embedded_views_preview flag to info.plist in iOS).

The WebView_FLUTTER plugin supports the new Android Platform Views mode but currently needs to be enabled manually. We will enable it by default in future releases once it is used more widely in the wider community.

The Google Maps and WebView plug-ins have already benefited from Platform Views improvements. If you want to use Platform Views to host your own Native UI components on iOS or Android, learn how to use Platform Views to host Native Android and iOS Views on Flutter.

The Navigator 2.0

If you have used Flutter application beforenavigationYou may have noticed that the core data structure (the stack of pages the user is browsing) is hidden from you. Instead, to manage, callNavigator.pop()_ _ orNavigator.push(). For example, suppose you want to display a list of widgets on the home page and allow the user to click on a Widget to go to a detail page dedicated to that color.The two screens can be implemented like this:

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),
     );
}
Copy the code

Using the simplest Navigator 1.0 style, you can navigate between the two screens in a seemingly simple way:

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)),
           ),
         ),
       ),
     );
}
Copy the code

Just a call to navigator.push () creates a two-page stack by pushing a new page at the top of the first page. However, unlike the list widgets created in the build method in the ColorListScreen page Containers, this stack is hidden from you. And because it’s hidden, it can be difficult to manage, for example dealing with deep links to initial routes provided by native embedding, or urls from the Web or intents from Android. Managing nested patterns between different permutations of the same page is also extremely difficult.

Navigator 2.0 solves these problems and more by making the page stack visible. Here is an updated example of navigation between ColorListScreen and 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; },),); }Copy the code

The application explicitly creates a Navigator and provides it with a list of pages that represent the entire stack. We create an empty _selectedColor to indicate that no color has been selected, so we do not show the original color of ColorScreen. When the user selects a color, we call setState() normally to indicate to Flutter that you want build() to call the method again. The method will now be ColorScreen to create a stack at the top. You can update the status in the OnPopPage callback, for example, if the user pops up, it means they have “unselected” the current color, so we no longer want that page displayed.

If Navigator 2.0 looks like the rest of Flutter, that is the intent — it is declarative, while Navigator 1.0 is imperative. The idea is to unify the model between navigation and the rest of the Flutter, while solving many problems and adding functionality. In fact, this little example has almost nothing to do with Navigator 2.0. For more information, I highly recommend the article on declarative navigation and routing in Flutter.

In addition, your existing use of Navigator 1.0 will continue as it does today and will not be removed anytime soon. If you like the model, you can continue to use it. However, if you try Navigator 2.0, we think you’ll like it.

Preview: Android state restoration

The new feature you can try out in this release is support for Android state recovery. This is one of our most popular features, with 217 likes!

For users unfamiliar with state recovery requirements, mobile operating systems may kill back-end applications in order to reclaim resources from foreground applications. When this happens, the operating system notifies the application that it has been terminated to quickly save any UI state so that it can be restored when the user loops back to the application. If implemented correctly, it can provide a seamless experience for users while making better use of the device’s resources. Until now, Flutter did not support state reversions, and it would be difficult to do state reversions properly without framework support. That’s why we’re excited to provide a base implementation of this feature for Android.

Here is a very simple example of restoring the default Flutter Counter application state:

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),
    );
}
Copy the code

Briefly, each widget has a Storage bucket and RestorationMixin registers it with a unique ID. By using a RestorableProperty type (the type RestorableInt used here) to store UI-specific data and registering that data with the state recovery feature, the data will be stored automatically before Android terminates the application, And when it returns to normal operation. That’s it. Any data stored in a Restoration * type, such as RestorableInt, RestorableString and RestorableTextEditingController (we have a heap of) will be restored. Also, if we don’t cover all the types you want to restore, you can create your own type RestorableProperty by extending it.To automatically test state recovery, we askedWidgetTesterAdd newrestartAndRestore API. The easiest way to test Flutter manually is to start the Flutter app with state recovery enabled on your Android device, enable “Don’t Keep Activities” in your Android developer Settings, run the Flutter app, put it in the background, And then we go back to it. At this point, Android will terminate and resume your application, so you can see if everything is working as expected.

While we are happy to put a preview of state recovery in your hands, there is more work to be done. For example, state recovery is not only available on Android, iOS apps can benefit as well. In addition, we are busy updating our own widgets to maintain their state during the recovery process. We already have support in Scrollable classes such as ListView and SingleChildScrollView (remembering the user’s scrolling position) and TextFields (recovering text entered by the user), and we plan to extend it to other widgets.

However, the key recovery support we haven’t added yet and what makes it a preview release is Navigation (1.0 or 2.0). This means that your user’s location in the application will not be restored. This feature will be released soon in Beta and in the next stable release of Flutter.

Preview: Smooth scrolling to provide mismatched input and display frequency

The Flutter team worked with internal Google partners to greatly improve scroll performance when input and display frequencies were different. For example, the Pixel 4 input runs at 120hz, while the display runs at 90hz. This mismatch can cause performance degradation when scrolling. Using the new resamplingEnabled flag, you can take advantage of the performance work we’ve done with Flutter to solve this problem:

void main() {
  GestureBinding.instance.resamplingEnabled = true;
  run(MyApp());
}
Copy the code

Depending on the frequency difference involved, enabling this flag can reduce vibration during rolling by up to 97%. When we determine that this is the best experience, we plan to enable this flag by default in future releases.

New unified Dart developer tools

As always, the update to Flutter means not only the engine and frame, but also the tools. Flutter 1.22 includes a new version of Dart (2.10) as well as a new Dart CLI tool that you may also find useful.

Dart has a history of many smaller developer tools (such as DarTFmt for formatting and Dart Analyzer code analysis). A new feature in Dart 2.10 is a unified developer tool for Dart that is very similar to the FLUTTER tool.Starting with today’s Flutter 1.22 SDK, you will find that this /bin folder (where you may have PATH) contains both the Flutter and dart commands. For more details, seeDart 2.10 blog post.

App Size analysis tool

The tools released as part of Flutter 1.22 include a new output size analysis utility. This tool helps diagnose Flutter if your application size subdivision changes over time.

You can use the tool to collect data for analysis by passing the — analysis-size flag to any of the following commands:

  • flutter build apk
  • flutter build appbundle
  • flutter build ios
  • flutter build linux
  • flutter build macos
  • flutter build windows

Use this flag when building a Flutter output artifact to print a summary of the artifact size and composition. This includes native code, assets, and even compiled package-level breakdown Dart code.Breakdown of the Flutter Gallery’s release APK

This summary helps quickly identify hot spots in the application’s package size usage. In addition, the collected data can also be provided as JSON files for use in DevTools, which allows you to further explore your application content, locate size issues, and see the changes between two different JSON files through the followingDescription of flutter. Dev. After loading the JSON file, you will have an interface that gives you a tree of application sizes. An example APK breakdown in Dart DevTools

For more details on what you can do with the App Size tool, read the documentation using the App Size tool on flutter. Dev.

Preview: Updated web page in DevTools

Another DevTools preview feature in this release is the ability to view the HTTP and HTTPs response Body in the Network TAB.To enable this feature, ensure that you enter the Flutter developer channel through Flutter Channel Dev and Flutter Channel Upgrade.

In addition, for applications with a lot of network traffic, we provide search and filtering capabilities.For documentation on the Network TAB, see flutter. DevUsing the Network View.

Managed DevTools inspector TAB in IntelliJ

We have been maintaining two copies of some of the Flutter tools for some time, such as the Inspector pane in IntelliJ and the Inspector TAB in Dart DevTools. Not only did this slow us down, as we had to maintain two code bases, but certain features were not yet included in the IntelliJ plug-in, such as Layout Explorer. So, to address these two issues, we enabled the ability to host the Inspector TAB directly from within IntelliJ with Dart DevTools.Notice that the Layout Explorer has been added, which you can use next to your code. To enable this option, go toPerferences > Languages & Frameworks > Flutter > Enable embedded DevTools inspector.

Improved output links in Visual Studio Code

The normal activity that a Flutter developer faces is from error output in a terminal or stack trace. In the latest version of the Flutter extension for Visual Studio Code, these links can now be properly parsed so that you can enable links directly from the output.This may seem like a small thing, but initial feedback on this feature has been very positive.

As usual, the list of tool changes here is too large, but I recommend the following announcement for details:

  • The Dart DevTools – 0.9.0
  • The Dart DevTools – 0.9.1
  • The 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

Focus customer: EasyA

EasyA is a subscription app designed to enable age-appropriate students to connect with great tutors via instant messaging, written using Flutter. It was recently featured by Apple as”Daily application”.

“When the school went online earlier this year, we knew we needed to jumpstart the tutoring app to help students. The amazing pace of Flutter development means that we are able to implement award-winning designs for iOS and Android, and publish them on the Web — lock them in! Often, this is virtually impossible. However, because Flutter allows us to target all three platforms simultaneously, we are able to share code efficiently and take full advantage of our small team of developers.”

— > EasyA co-founder Phil Kwok

A major change

As always, we try to keep the number of major changes to a minimum. This is the list in the Release of 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.

conclusion

The Stable version of Flutter 1.22 came out soon after the previous version, but it contains too many good things to list in this article. We hope this release helps you develop great apps for iOS and Android, and we can’t wait to see what’s in your store! Thank you for your support — we build Flutter for you.