What’s New in Flutter 2. by Chris Sells
By: Chris Sells
Tags: Desktop, Web Development, Flutter, Dart, Web

Folio is meant to be a simple example of an app that you’d want to run well on multiple platforms from a single code base. And by “well,” we mean that it looks good on small, medium, and large screens, that it takes advantage of touch, keyboard, and mouse input, and that it works well for the idioms of the platform, (for example, by using links on the web and menus on desktop). We call this kind of app “platform adaptive” because it adapts well to whatever platform it’s running on.

If you’d like to see how you can make your own apps platform adaptive, you can check out the source code for Folio. In the future, expect to find docs and codelabs that explore this topic more deeply. In the meantime, check out Aloïs Deniel’s excellent blog post and video on this very topic.

Google Mobile Ads to Beta

In addition to Flutter desktop moving to beta, today we’re excited to announce an open beta for Google Mobile Ads SDK for Flutter. This is a brand new plugin that provides inline banner and native ads, in addition to the existing overlay formats (overlay banner, interstitial, and rewarded video ads). This plugin unifies support for Ad Manager and Admob, so no matter what size publisher you are, this plugin can be tailored to your scenarios.

We’ve been piloting this plugin with some of our early customers in a private beta program, and many of them have successfully launched their apps with these new formats. For example, Sua Musica (largest Latin American music platform for independent artists with more than 15k verified artists and 10M MAU) launched their new Flutter app with the Google Mobile Ads SDK for Flutter plugin. They saw an 350% increase on Impressions with a 43% increase on CTR and 13% increase on eCPM.

This plugin is available for you to use today. As part of Flutter Engage, Andrew Brogdon and Zoey Fan presented a session on “Monetizing apps with Flutter” (available on the Flutter Engage site), where they talk about monetization strategies for apps built with Flutter, and how you can load ads in your Flutter app. Moreover, we created a new Ads page on flutter.dev where you can find all helpful resources such as the plugin implementation guide, the inline banner and native ads codelab, and the overlay banner, interstitial and rewarded video ads codelab. Please be sure to check them out!

New iOS features

Just because we’re continuing to increase the quality of support for other platforms, don’t think we’re forgetting iOS. In fact, this release brings with it 178 PRs merged that are iOS-related, including 23495, which brings State Restoration to iOS, 67781, which fulfills a long-standing request to build an IPA directly from the command line without opening Xcode, and 69809, which updates the CocoaPods version to match the latest tooling. In addition, a few iOS widgets have been added to the Cupertino design language implementation.

A new CupertinoSearchTextField offers the iOS search bar UI.

The CupertinoFormSection, CupertinoFormRow, and CupertinoTextFormFieldRow widgets make it easier to produce validated form fields with iOS’s sectioned visual aesthetics.

In addition to the feature work for iOS, we’re continuing to research performance improvements for iOS and Flutter in general when it comes to shaders and animation. iOS continues to be a premier platform for Flutter and we’ll continue to work to bring important new features and performance improvements.

New widgets: Autocomplete and ScaffoldMessenger

This release of Flutter comes with two additional new widgets, AutocompleteCore and ScaffoldMessenger. AutocompleteCore represents the minimal functionality required to get auto-complete functionality into your Flutter app.

Autocomplete is an often-requested feature for Flutter, so this release starts to provide this functionality. You can use it today, but if you’re curious about the design for the complete feature, check out the autocomplete design document.

Likewise, the ScaffoldMessenger was created to deal with a number of SnackBar-related issues, including the ability to easily create a SnackBar in response to an AppBar action, creating SnackBars to persist between Scaffold transitions, and being able to show SnackBars at the completion of an asynchronous action, even if the user has navigated to a page with a different Scaffold.

All of this goodness can be yours with a couple of lines of code that you should be using from now on to display your SnackBars:

final messenger = ScaffoldMessenger.of(context);

messenger.showSnackBar(SnackBar(content: Text(‘I can fly.’)));

As you might imagine, there’s more to it than that; for the details, check out an excellent video from Kate Lovett on ScaffoldMessenger.

Multiple Flutter instances with Add-to-App

We know from talking with many Flutter developers that a significant number of you don’t have the luxury of starting a brand new app but you can take advantage of Flutter by adding it to your existing iOS and Android apps. This feature, called Add-to-App, is an excellent way to reuse your Flutter code across both mobile platforms while still preserving your existing native code base. However, for those of you doing that, we’ve sometimes heard that it’s unclear how to go beyond integrating the first screen into Flutter. Interweaving Flutter and native screens makes navigation states difficult to maintain, and integrating multiple Flutters at the view level uses a lot of memory.

In the past, additional Flutter instances had the same memory cost as the first instance. In Flutter 2, we’ve reduced the static memory cost of creating additional Flutter engines by ~99% to ~180kB per instance.

The new APIs to enable this are in preview on the beta channel and are documented on flutter.dev along with a set of sample projects demonstrating this new pattern. With this change, we no longer hesitate to recommend creating multiple instances of the Flutter engine in your native apps.

Flutter Fix

Whenever any framework matures and gathers users with larger and larger code bases, the tendency over time is to avoid making any changes to the framework API to avoid breaking an increasing number of lines of code. With over 500,000 Flutter developers across a growing number of platforms, Flutter 2 is quickly falling into this category. However, for us to continue to improve Flutter over time, we want to be able to make breaking changes to the API. The question becomes, how to continue to improve the Flutter API without breaking our developers?

Our answer is Flutter Fix.

Flutter Fix is a combination of things. First, there’s a new command-line option to the dart CLI tool called dart fix that knows where to look for a list of deprecated APIs and how to update code using those APIs. Second, it’s the list of available fixes itself, which is bundled with the Flutter SDK as of version 2. And finally, it’s an updated set of Flutter extensions for the VS Code, IntelliJ,and Android Studio IDEs that know how to expose that same list of available fixes as quick fixes with little light bulbs that will help you to change the code with a click of your mouse.

As an example, let’s say you had the following line of code in your app:

Creating a Flutter widget using a deprecated argument

Because the argument to this constructor is deprecated, it should be replaced with the following:

Creating a Flutter widget with the deprecated argument replaced

Even if you’re familiar with all of the many Flutter deprecations, the larger the number of changes you have to make in your code, the harder it is for you to apply all of the fixes and the easier it is to make mistakes; humans are not great at these kinds of repetitive tasks. But computers are; by executing the following command, you can see all of the fixes we know how to make across your entire project:

$ dart fix --dry-run

If you’d like to apply them in bulk, you can easily do so:

$ dart fix --apply

Or, if you’d like to apply these fixes interactively in your favorite IDE, you can do that, too.

While we’ve been marking old APIs as deprecated for a number of years now, now that we have a policy about when we will actually remove deprecated APIs, Flutter 2 is the first time that we’ve done so. Even though we haven’t yet captured all of the deprecated APIs as data to feed Flutter Fix, we continue to add more from previously deprecated APIs and will continue to do so with future breaking changes. Our goal is to do our best to make Flutter’s API the best it can be while also keeping your code up to date as we do it.

Flutter DevTools

To make it clear that DevTools is a tool that should be used for debugging your Flutter apps, we’ve renamed it to be Flutter DevTools when it’s debugging a Flutter app. In addition, we’ve done a lot of work to bring it to production quality worthy of Flutter 2.

One new feature that helps you zero in on your issues even before you’ve launched DevTools is the ability for Android Studio, IntelliJ, or Visual Studio Code to notice when there’s a common exception and offer to bring it up in DevTools to help you debug it. For example, the following shows an overflow exception has been thrown in your app, which brings up an option in Visual Studio Code to debug the issue in DevTools.

The Flutter IDE extensions notice when your app throws a layout overflow exception

Pressing that button brings you right to the Flutter Inspector in DevTools on the widget that’s causing the trouble so you can fix it. We’re only doing this for layout overflow exceptions today but our plan is to include this kind of handling for all kinds of common exceptions for which DevTools can be the solution.

Once you’ve got DevTools running, new error badges on the tabs help you track down specific issues in your app.

The red dots in DevTools helps you focus on the parts of your app with errors

Another new feature in DevTools is the ability to easily see an image that’s at a higher resolution than it’s displayed, which helps track down excessive app size and memory usage. To enable this feature, enable the Invert Oversized Images in the Flutter Inspector.

Enable the “Invert Oversized Images” option to highlight images that are bigger than they need to be

Now, when you display an image that’s significantly larger in resolution than its display size, it will appear upside-down to make it easy to find in your app.

The “Invert Oversized Images” option in action

Also, by popular demand, in addition to showing details about flexible layouts in the Flutter Inspector’s Layout Explorer, we’ve added the capability to show fixed layouts as well, enabling you to debug layouts of all kinds.

The new Layout Explorer shows layout details for fixed as well as flex layouts

And that’s not all. Here’s just a summary of a few more of the new features in Flutter DevTools 2:

Added average FPS information and usability improvements to the Flutter frames chart

Calling out failed network requests in the network profiler with red error labels

New memory view charts are faster, smaller and easier to use, including a new hovercard to describe activity at a specific time

Added search and filtering to the Logging tab

Track logs from before DevTools is started so you can see the complete logging history when you do start it up

Renamed the “Performance” view to “CPU Profiler” to make it more clear what functionality it provides

Added timing grid to CPU Profiler flame charts

Renamed the “Timeline” view to “Performance” to make it more clear what functionality it provides

And that’s still not all. For the full set of changes, I recommend the following announcements:

Android Studio/IntelliJ Extension

The Flutter plugin for the IntelliJ family of IDEs has gained a number of new features for Flutter 2 as well. To start, there’s a new project wizard, which matches the new wizard style in IntelliJ.

Also, if you’re using IntelliJ or Android Studio on Linux to program against the Flutter SDK installed from the Snap Store, the Flutter snap path has been added to the list of known SDK paths. This makes it easier for users of the Flutter snap to configure the Flutter SDK in Settings. Thanks to MarcusTomlinson@ for this contribution!