Skip to content

Tag: flutter

The Value in Changing to Flutter – Part 1

Hi there, and thanks for reading!  This is my first article about Flutter on this site.  I’ve taken a “Flutter from scratch” approach with the idea that if you are reading this, you probably already use a mobile development framework like Xamarin Forms or Ionic. 

My blog is a little anaemic at the moment as I try to find time between my day job and other responsibilities, but I’ll definitely continue this series and add more content as time goes on.

Switching to a new mobile development framework is a huge investment in time and mental energy.  Whether you make apps on the side as part of your hobby, or work as part of a team making something bigger, you probably already have an existing code base.  More than that, you have the skills today to make an app with.

So, why would you leave all that and even consider switching to a completely new framework like Flutter?  Simply put, the answer is the value in switching to Flutter has to exceed  just staying with your existing framework.  In exchange for learning a new language (Dart), a new native development framework (Flutter), a new way of testing your apps, a new business logic/UI pattern (like BLoC), you have to get something from your existing framework that you’re not getting today.

In my case, I had written a few apps in Xamarin Forms, and had spent years in the C# language.  Switching to a new framework with a new language (!!) was a daunting concept.  In another post, I’ll focus on why Dart is probably a lot like the language you use today (and how easy the switch can be) but today I want to talk about the value in Flutter.  I came from Xamarin Forms (and Ionic before that) so I will compare some functionality in those frameworks to their equivalents in Flutter.

Declarative UI code

When you first fire up your brand new Flutter app (that you just made with the ‘flutter new’ command) you will get this stashed into your main.dart file.

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

For someone starting with Flutter,  a one hundred and eleven line file  (with comments – I took out the comments for brevity) is quite long, and maybe a tad overwhelming.  Plus, coming from XAML or HTML, it could even look a little chaotic.  You’re not alone in thinking that.  Initially, this turned me off Flutter because I thought that what was here was the minimum level of code to get something to build or display something on a screen.

It’s quite large for two reasons.  One, the app actually does something (tapping a button on the screen increments the onscreen counter by one).  It’s more than just “Hello World” on a label.  It’s actually trying to introduce you to how important the setState() function is, but that’s something we’ll delve into in another article.

The second reason is that is uses declarative UI.  This is a huge topic in itself, but one of the massive benefits of this approach, is that you write your UI in the same language that you write your business logic code in.  Immediately that might make you worry, as you try to picture writing a web app entirely in HTML or Javascript.  But here’s the thing – in frameworks like Xamarin Forms, your XAML actually gets compiled to BAML (Binary Application Markup Language), which is then used by the app itself.  That’s great, but what happens if there is a bug in that compilation process?  Or, even worse, what if you type something that looks fine in your editor, but throws an exception when the device evaluates the BAML?

Many hours I have spent in almost this exact pose trying to debug a weird XAML issue.

The answer is simple.  Your app will build and deploy just fine, but when someone tries to use that page, it will throw an error.  And if there is no error handling around your code (or a global error handler, because this error has occurred in your XAML), your app will just crash.  Or the navigation will fail, leaving the app in a weird state and your user trying to navigate to that page again and again with no idea what is happening behind the scenes.

And when you’re spending hours trying to find that bug in your XAML, these are the times when you’re not being productive implementing new features, or fixing bugs.  This is when your productivity is at its lowest, or even at a standstill.

These are the times when you are not delivering value, you’re just plugging away to try to fix a bug.

Hours turn to days.  Days to weeks.  Your Google searches yield results from people who had the same-ish issue as you, but like, six years ago.  You ask a question about this issue on Stack Overflow, but your problem is too niche to elicit any useful replies from the community.  Eventually, after peering through row by painful row of your changes since your last commit, you sigh, and git reset –hard, and try the implementation again.  Maybe there’s something wrong with how you did it you think, maybe next time I won’t run into the same issue.  And maybe you won’t. Maybe.

Okay that sounds horrific, how is Flutter any better?

With Flutter, the underpinning language is Dart (as I mentioned above).  It’s a type safe language, so if you try to do something that doesn’t make sense (like a type conversion that just wouldn’t work )then this is picked up before you deploy your code.  In fact, your code won’t even build, because whether you made a typo or a mistake in your UI code, or in your view model code, or your services, it’s all the same level of type safety.  It’s all just Dart.  What would happen in something like Xamarin Forms?  Let’s take a look.

First, we set up a boolean property in our ViewModel.  We’ll call it “BindingTest”, make it public and assign it to false.

Then, we try to use it in our XAML in some spaces that booleans should not be allowed in.  In this example, I’ve used it for TextColor, TextDecorations and Margin.

If you’ve ever used Visual Studio, you’ll notice there are no squiggly lines underneath these assignments.  Visual Studio will happily let you set these assignments.  And,  you could also build and deploy this app.  Then, in your app, it just looks like this:

But how would you know that this label looked like this because you assigned it the wrong type?  The only warning you get is this message in the output window (which is presented alongside a raft of other messages).

We can see the binding errors  where it can’t convert  from boolean to the type it was expecting.

What’s it like in Flutter?

We’ll do the same thing.  We’ll make a boolean and try to assign it to something that’s supposed to be a colour.

Straight away, it doesn’t work.  Because the UI is written in Dart, and it is type safe, it doesn’t allow its use like that.  You can’t build your app like this, and you definitely can’t deploy it.  You don’t have to pick through a output window to work out why your app won’t build.  Any errors or typos that result in errors like the above are caught immediately.

There are other massive benefits to a declarative UI, and using the same language between UI and other parts of your app.  For example, all the cool language features you learn in any part of your app can be used in your UI, or service layer, or anywhere else really.

Hopefully I’ve been able to share with you the benefit of Dart’s declarative UI, and the value it can bring to you as a developer.  If you enjoyed the article, be sure to let me know in the comments.

Thanks for reading!

Lewis