Round Two with Flutter – Is it a knockout?

This is round two with Flutter. I looked at Flutter last year, but it seemed still a little early to put it to serious work. A lot has changed in the past 18 months. Has Flutter matured to the point that it can be used as a mainstream mobile development tool and will it really allow for one codebase for both Android and iOS Apps? What is the state of tooling to make a developer’s life enjoyable? Let’s find out!

Like many of my other posts, I will update as I explore and learn more.

The Bell Rings for Round Two

I originally started looking at Flutter in September 2019. At the time it seemed pretty interesting. I’ve used many cross-platform tools like PhoneGap, Ionic, AppGyver, Appcelerator, and Xamarin, but for various reasons I really didn’t see any of those as broadly usable. Flutter was the first one where I could see the potential, but I thought it needed a bit more baking in the oven.

So here we are again. I have the same MacBook Pro, but it is updated with the latest macOS (10.15.7 at the time of writing). I’m up to date with all libraries and IDE updates (Android Studio 4.02 and MS VSC 1.50.0) and will be working with Flutter 1.22.1 and Dart 2.10.1.

IDE Support Android Studio or Visual Studio Code?

Refactoring Support in VSC

Great news is – there are options! Obviously there is Android Studio, which was true last year, but MS Visual Studio Code (VSC) is not only a good option, but VSC does a few things BETTER than Android Studio (AS). For example, refactoring options in VSC are dramatically richer than in AS. For example you can place the cursor in a Column and then pick off refactoring to re-wrap the element (well a Widget really) in a surrounding Widget type. VSC will add all the code for you. Pretty slick.

Working with emulators and simulators is a bit easier in Android Studio. First of all you get automatic updates notices in Android Studio for all components. If you have already started a simulator for the command line or from within XCode, you can kickoff builds for iOS simulators right from within Android Studio. Hot reloads also work pretty flawlessly for both Android and iOS run-times, unlike last year when that was not true. You can do this in VSC as well, but in my opinion its not quite as intuitive.

I have not made up my mind which IDE is better. VSC is lighter weight in terms of system resources and I’m using it for many other frameworks and for kubernetes work too. It is nice to have one IDE for all the things I do, but since my own primary interest is with Android (I use an Android phone) I lean towards Android Studio.

VSC Layout Guides

When working with a highly nested structure, as you will no doubt do with even a moderate;y complex layout, VSC does a better job helping with indentations and also auto inserts comments to show where UI Widgets end. AS does something similar, but the VSC implementation is better. AS does not help with comment insertions.

VSC and AS have a “Dart DevTools” feature available from the debug console mode that provides a lot of details about your app: performance, memory consumption, and most importantly a layout inspector. Opening Dart DevTools in AS pops open a window in Chrome. Doing the same in VSC opens the window as a new panel in the IDE. I prefer the AS implementation because I can pull the Chrome window to a second monitor. Personal preference I suppose. I think that is basically the case for the IDEs –> personal preference as to which you like best.

For now I think I will be using both IDEs until I can really decide which I prefer. It is great to have two options that work well together. There of course is some need to still use XCode for some things – certificates and such for example. To use XCode for that simply navigate in your project to the iOS folder and open the Runner.xcodeproj file and adjust settings as needed. It would be nice to completely eliminate XCode.

New and Interesting in Flutter 2020

Definitely in the year since I last used Flutter, things have improved. It starts with the basic tooling being more reliable. Features in the IDEs have improved and are much more stable. Hot re-load works reliably with both iOS and Android when emulators and simulators are started manually or from within the IDE. Layout hierarchy and the consistency of Widget behavior/methods has improved quite a bit.

Dev Tools Layout Inspector

Dart DevTools is a huge improvement, especially the layout inspector. Layout inspector gives you a great view, similar to what you have in web tools like Chrome or Firefox developer tools. Padding, margins, alignments – this is a great tool for checking your layouts.

When using Dart tools, the performance, timeline, and a few other features require you to be running in profile or release mode. In order to do that you need to have an emulator running in 64-bit mode. Use the Android Virtual Device Manager to download an image since these are not included by default in AVD.

To run an app you need to Select Run and then Profile from the main menu… in Android Studio. Then select the main.dart file with the Flutter icon next to it. Then select “Profile” from the pop-put menu.

In Visual Studio Ccode on the main menu, go to Run and Open Configurations (aka the launch.json file). Then add a flutterMode parameter for the project and set it to profile. Then start the app. When done remove this or set it back to debug.

Flutter Tips and Tricks

Working with Flutter is fairly straightforward, but there can be all sorts of things that all of a sudden become issues. Here’s a section of tips and tricks for when things went awry with my work.

At one point the Android Virtual Device Manager (AVD) started throwing an error when I would start an emulator from Android Studio (VSC was not effected). For some reason AS cannot find the binary for AVD anymore. I fixed this issue by adding some lines to the .zshrc file (with the Catalina release I have switched over from the bash shell) and also adding ANDROID_HOME references to the path like this:

export ANDROID_HOME=/Users/$USER/Library/Android/sdk
export ANDROID_SDK_ROOT=$ANDROID_HOME
PATH="$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/tools:$ANDROID_HOME/platform-tools"
Android Binary Image Selector

The full Dart DevTools package requires you to have a 64-bit virtual device installed and running. To do that, go into the AVD, create a new device, pick the phone model and hit next, then instead of selecting a recommended image, select the x86 tab, and finally pick an ABI (Android Binary Image) with an _64 in the name.

From Android Studio you can build and debug an app in the Android and iOS simulator simultaneously. Run an iOS simulator by executing “open -a simulator” from the terminal (or from the device menu in AS). Startup and Android simulator from the AVD. Then you can switch back and forth between them:

Multiple Simulators

Making careful use of final and const keywords is important in Flutter. In large apps ensuring that Widgets and UI elements that are stateless use final for vars and const for both variables and constructors can have a big benefit on overall app performance. The same is true when declaring Widgets. Having the const keyword tells the Flutter render engine that the element will never change. In larger apps this will payoff with faster screen refreshes.

Important Flutter Resources

Flutter – Yeah is it really One Codebase?

There’s no doubt you can build one app for both Android and iOS, however the resulting app does not really comply with the full design specs for each platform. No – sorry not one code-base to rule them all. That’s the real truth. There are ways to minimize re-coding, but there are significant gaps. Just look at the main app class MaterialApp vs. CupertinoApp the parameters and capabilities do not match.

No doubt you can do a lot with ternary expressions to minimize re-coding, but it is a reality that you must deal with. So get used to code like this:

    return Platform.isIOS
        ? CupertinoPageScaffold(
            child: body,
            navigationBar: appBar,
          )
        : Scaffold(
            appBar: appBar, //AppBar
            floatingActionButton: Platform.isIOS
                ? Container()
                : FloatingActionButton(
                    child: Icon(Icons.add),
                    onPressed: () => _startAddNewTransaction(context),
                  ), //End FAB
            body: body,
          );

In order to deal with the differences like the above where a Floating Action Button is normal on Android, but not on iOS.

Conclusions

Flutter and its underlying languages have improved dramatically over the past year. Upgrades are smooth and things don’t break. There are a slew of improvements to the Dart language itself and Flutter’s key components. I find using Flutter and Dart as quite enjoyable. There is a lot to know, but it is a fun, modern language and framework.

IDE support is excellent and there are two very robust options in MS VS Code and Android Studio. The differences between these two tools comes down to personal preference. I do not see a reason to choose so I will continue to use both. Definitely the refactoring options in VSC are superior to AS, even with the Live Templates in AS.

I think it is an easy decision for a small startup or a company with a very small portfolio of software products to go with Flutter. For a larger enterprise it becomes more difficult. Flutter brings along a new language to support and a new way to build a GUI. Comparing this to a JavaScript based framework like React Native shows many of the same benefits without having to learn Dart and React Native shares a lot with React. In a large enterprise scaling development resources with JavaScript as a full stack probably still makes more sense.

So – not a complete knockout, but depending on your company, maybe a TKO.

2 Responses

  1. Matt Howey says:

    So, React Native?

    • Yeah? React Native is pretty compelling too. I do think there are advantages to Flutter. Dart is a modern and much more robust programming language than JS for one thing. Performance is another. However for big shops like where I work the appeal of standardizing on JS across the full stack is a pretty compelling reason to go for RN.

Leave a Reply

%d bloggers like this: