Let's Work Together

Flutter Takes Off at Google I/O 

Image by Brandon Wever

Flutter is Google’s mobile app SDK for crafting high-quality native interfaces on iOS and Android in record time. This year’s Google I/O conference prominently featured Flutter alongside native development experiences.

Cross-platform solutions for mobile applications have been around as long as there have been smartphones. From early HTML based solutions such as Cordova to more “native” solutions like Xamarin and React Native, the goal to “write once and deliver everywhere” has been out of reach. These platforms usually have some pitfalls, such as responsiveness, poor platform support, or just lousy development experiences. Are all cross-platform SDKs 💩? Why are we even talking about it? Is it worth learning instead of writing two apps in Swift and Kotlin?

Well, Google is throwing their hat into the ring with Flutter, and from the sessions at I/O they are aiming to address everything terrible about cross-platform SDKs and make a genuinely delightful mobile development experience. Flutter touts features such as sub-second stateful reloading, reactive user interface programming, and a strong type system that supports test-driven development. 

Features of Flutter

Fast development is the main feature Flutter is selling; it’s the first bullet point on Flutter’s Website. So what makes developing for Flutter faster than the “old-fashioned” mobile development way?

Single Codebase - Two Apps

Flutter delivers on its promise of code reuse. By handling the drawing of “widgets” inside the Flutter runtime, you can leverage Material Components on Android and iOS or Cupertino (Apple Theme) on iOS. Your all-important business logic no longer needs to go through translations to reach your customers, no need to reimplement your API on iOS in Swift and Android in Java or Kotlin.

Two apps! One codebase!
Two apps! One codebase!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    String platform = Theme.of(context).platform.toString();
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text('You\'re running the app on $platform!'),
          ],
        ),
      ),
    );
  }

The above code example is running on an iPhone X simulator as well as an Android emulator running Android P. As you can see, Flutter has resources to determine which platform you are targeting if you wanted to differentiate your app per platform. Flutter even offers a second set of widgets named “Cupertino” which will give the app that iOS-feel.

Sub-second Hot Reload

As native developers, we’re all familiar with minute-long compile times. Even though build times have gotten better, there is still no competition with what I consider the killer feature of Flutter.

With Flutter you can make a code change, whether it be style or business logic, save the file, and by the time you tab over to the emulator of your choice, the code change is applied to the running app.

Hot reload so fast

In the above recording I was able to make a change, save the file, and in 445ms the change was applied to the running app. The hot reload is also stateful so, if you are testing a screen that is 12 layers deep in the app, you won’t have to navigate back to it every time you make a change.

Modern Reactive Architecture

Flutter uses either Stateful or Stateless widgets to render your app on the screen. These are like Containers and Render Components respectively for those of you familiar with React-Redux. Stateful widgets are usually the high-level components of the screen, with Stateless components being reusable layouts like card views, images, and text. Since Flutter focuses on favoring Composition over Inheritance, you can focus on making reusable widgets that can be plugged in throughout your app. In fact, I think the style of Flutter’s layout code encourages it, as if you are nesting too many widgets without breaking them into separate Stateless widgets, you could end up with a pyramid of parenthesis in your code 😷.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: new FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: new Icon(Icons.add),
      ),
    );
  }
}

The above is what is part of what is generated for you when running flutter create demo (minus all the comments). As you can see, any time the Floating Action Button is pressed, the increment method will call setState with a counter that is one larger than before. Since this is in the setState block, Flutter will do its magic and see what needs to be rerendered, in this case, it is the second text widget. You can think of how easily this would extend to rendering loading states, error views, form input, etc.

What Flutter Means for You

You may not want to go out and rewrite your whole app in Flutter just because its the new kid on the block, but I would not turn my nose up at it. Native mobile developers have a strong feeling towards cross-platform solutions since many have come and gone without ever really delivering that true native feel. I think Flutter comes pretty close to solving that unsolvable problem of two codebases for your mobile apps. Flutter has a delightful developer experience, very informative and detailed documentation (seriously, for a beta these docs are insane, check them out on Flutter’s Website), and great tooling for debugging and code completion. You might want to look into Flutter the next time you are sizing up a project, to see if it’s right for you. While there are still some rough spots such as no interactive Google map support, no implementation into existing mobile apps, and a larger than native app size, the Flutter team is constantly making improvements without many breaking changes. If you want some more hands-on experience, take a look at one of Google’s many codelabs. 

The Atomic Robot team is very excited about all the announcements at Google I/O. We’re eager to build new experiences with tools like Flutter, MLKit, and Firebase. If you have a project you’re ready to get started on or need new team members to take you that last mile, we’d love to talk to you at https://atomicrobot.com/contact/.