Flutter app development tutorials by Andrea Bizzotto

What's great about Flutter?

In this article I'm going to tell you everything that you need to know about Flutter, and cover all of these different topics:

This is for you if you've heard about Flutter, and want to learn what it's all about. Or you are considering it for your next project, and want to get a high level overview.

And I will also share some relevant things that were revealed at Flutter Interact.


And just to be clear, this is not a comparison of Flutter with other app development frameworks (native iOS & Android, React Native & Xamarin). While this comparison would be useful, I only have a little working knowledge of some of the other frameworks, and I would not be able to make a good assessment of their strengths and weaknesses.

As far a Flutter goes, I want to tell you what I love about it, what I like about it, and what things should be improved.

This is all based entirely on my own experience using Flutter. All opinions are my own.

So sit comfortably, get a nice drink, and enjoy the read. πŸ˜‰

And I promise you, that if you make it all the way to the end, I will share a special secret with you. 🎁

What is Flutter

According to the official website:

Flutter is Google’s UI toolkit for building beautiful, natively compiled applications for mobile, web, and desktop from a single codebase.

There are many things that make Flutter a great framework for mobile app development. And I want to start by focusing on the #1 selling point.

Multi-Platform Development

Flutter is already production-ready for Android and iOS. As of December 2019, it supports web (beta) and desktop (alpha).

With Flutter you can write code once in Dart, and run it on multiple platforms.

Compared with other cross-platform frameworks, the key difference is that Flutter controls every single pixel that is drawn on screen.

Flutter follows platform-specific behaviours and conventions. This means that Flutter apps look and feel native both on iOS and Android.

Scrollable lists are an example of this.

  • On iOS, we get a native bounce effect when we overscroll.
  • On Android, scrolling stops when we reach the end of the content, and we get a material splash effect instead.

And this is all accomplished with exactly 0 lines of code.

So when it comes to platform differences, you'll find that in most cases Flutter does the right thing out of the box.

But of course, you have full control on how your apps look and feel. For example, you can override the default platform scroll-physics, using any of the available ScrollPhysics subclasses.

Crafting custom native UIs

How do we make UIs look native in Flutter?

Flutter supports both Material Design and the Cupertino design language.

When you build a new mobile app, you'll most likely use Material design, which is a coherent design language that applies to text, buttons, navigation elements and much more.

But if you want you can use the Cupertino widgets.

And you are completely free to customise the way your UI looks on each platform.

The simplest way to do this is to use the so-called platform-adaptive widgets (e.g. Switch.adaptive). These are common UI elements that look and feel native on each platform.

And where platform-adaptive widgets are not available, you can use platform toggles to choose different UI controls depending on which platform you're running on:

if (Platform.isIOS) {
  // Use Cupertino on iOS
  return buildCupertinoWidget(context);
}
// Use Material design on Android and other platforms
return buildMaterialWidget(context);

If you want, you can even build your own abstractions on top of this, and more easily reuse platform-specific code in your projects:

/// Base class to be extended by all platform aware widgets
abstract class PlatformWidget extends StatelessWidget {
  PlatformWidget({Key key}) : super(key: key);

  Widget buildCupertinoWidget(BuildContext context);
  Widget buildMaterialWidget(BuildContext context);

  @override
  Widget build(BuildContext context) {
    if (Platform.isIOS) {
      // Use Cupertino on iOS
      return buildCupertinoWidget(context);
    }
    // Use Material design on Android and other platforms
    return buildMaterialWidget(context);
  }
}

Custom styling & Typography

With Flutter you are not limited to the standard look of Material or Cupertino apps.

With Material theming, you can define high level style parameters that are consistent throughout your entire app.

Here's a variation of the same UI elements, using three different themes, as presented at Flutter Interact:

Not only that, but it was recently announced that the the entire catalog of Google Fonts is now available in Flutter. This means that you can make your app unique by choosing from a wide set of beautiful fonts.

Flutter really shines when it comes to customising UI and typography. And it looks and feels native.

But have you ever wondered how it does that?

Flutter controls every pixel on screen

Flutter apps do not use the native UI controls available on each platform.

Instead, Flutter comes with a rich set of widgets that are built to replicate the native controls with high fidelity.

Rendering is completely controlled by the Flutter SDK, which is composed by the Flutter framework and the Flutter engine:

This means that 99% of the time you'll be using APIs from the Flutter Framework.

And if you really can't find a high level API that does what you want, you can tap into the Flutter engine APIs.

Building UIs with Dart

With Flutter, UI layouts are built entirely in code, using a declarative style.

Almost everything that you see on screen is a UI component called a Widget.

And your entire app is represented by a so-called widget-tree, which is made out of widgets of different types. Example:

Widget trees are built using composition, using a declarative code style:

Widget buildContents() {
  return Padding(
    padding: const EdgeInsets.all(32.0),
    child: Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          RowWithLabel(
            text: 'Active',
            child: Switch.adaptive(
              value: true,
              onChanged: (value) => _platformSwitchChanged(context, value),
            ),
          ),
          SizedBox(height: 60.0),
          RowWithLabel(
            text: 'Inactive',
            child: Switch.adaptive(
              value: true,
              onChanged: null,
            ),
          ),
        ],
      ),
    ),
  );
}

With Dart, it becomes second-nature to write (and read) UI as code.

And as your layouts become more complex, you can break them up into multiple widget classes for better code reuse.

The declarative UI style has some profound implications in the way that apps are built.

It means that the only way to update the UI is by changing the application state.

Declarative UI is the only way, and since it is not possible to update the UI with imperative code, a whole class of problems and bugs completely goes away.

So with Flutter, the days of spaghetti-like, imperative UI code are gone.

Flutter doesn't use any CSS or JSX-style syntax to style UI components. Instead, both the UI layout and styling are written entirely in Dart.

This is a great thing, because Dart is a general purpose programming language.

And it supports "UI as code" control flow directives. In practice, this works extremely well.


One other profound advantage of declarative UI, is that reactive programming becomes easier to implement.

You can use observables (streams in Dart), to model your application state as something that can change over time.

And Flutter provides all the necessary APIs to implement reactive UIs with ease.

By the way, what I just said works both with local application state, and state that is stored somewhere in the backend.

If you use a realtime database such as Cloud Firestore, you can write your apps so that the UI automatically updates when the state changes on the backend.

Here's an example app with multiple counters that are kept in sync across multiple devices.

And this is possible because it uses Firestore as a single source of truth.

Developer Experience (Hot Reload)

I've been working with various types of UI frameworks over the last 15 years.

And I have to say that Flutter offers the best developer experience I have ever encountered.

This translates directly into developer productivity and happiness.

A lot of this has to do with hot reload, which allows us to edit our Flutter code, and see how it translates on screen with sub-second delay.

When iterating on UI designs, this is a game changer.

Time and again I've been able to implement fairly complex UIs, in a fraction of the time needed with conventional languages that don't support hot reload.

Hot reload in Flutter is so good that it enables new forms of collaboration. We can sit next to a designer, and make UI changes in realtime, without feeling embarrassed because we changed something and we have to wait for the whole app to recompile.

And this makes it worth it to add nuance and detail to our apps, and make our designers and users happy.

So what makes hot reload possible in the first place?

The Dart Language: Hot Reload

Dart is the only mainstream language that can be compiled both Just In time (JIT) and Ahead Of Time (AOT).

As you develop your apps, you can use the JIT compiler with hot reload.

But for release builds you can use the AOT compiler, which generates optimised machine code that runs on the physical hardware for your target platform.

In this respect I find that Dart has some very clever tooling infrastructure, which allows it to run on emulators, real devices, or even on the web.

A Brand New Dartpad

As of December 2019, you can test Flutter directly on the browser with the Dartpad editor.

This is a big step towards making Flutter more accessible. You can try Flutter and use it to prototype things, without installing all the required tooling. As an extra bonus, you can use Dartpad to resize your preview and simulate different screen sizes.

Dart Language Features

Dart supports hot reload and can run on multiple environments.

But what can we say about the language itself?

Some people have described Dart as a mundane, perhaps even boring language.

Personally, I feel that this can be a good thing. Because Dart is an easy language to learn, which gets the job done, without getting fancy and over-complicated.

And by the way, I'm the first to admit that Dart lacks some useful features that are present in other modern languages like Swift and Kotlin.

On the other hand, Dart is evolving quickly, and just this year alone, the Dart team has added many language features that increasingly make it a better language to work with.

And as a result, Dart has become the fastest growing language in 2019, according to GitHub.

Getting started

Alright, so how easy is it to get started with Dart and Flutter?

To answer that question, we need to look at documentation, support and the debugging experience.

Documentation

Flutter documentation scores very highly on my clock.

the Flutter website is a great place to get started. It includes clear installation instructions, and various codelabs to help you get familiar with the basics.

Beyond that, Flutter widgets are well documented, with short video tutorials explaining clearly what you need to know.

Flutter is open source, so all the documentation is one click away in our favourite IDE. This often includes sample code, making it easier to adopt APIs that we are not yet familiar with.

Debugging

Things don't always work the first time as we develop our apps. Sometimes we get runtime errors, and we need to debug our apps.

Debugging effort is an important criteria when evaluating a framework. In this respect, the Flutter team has gone to some great lengths to provide helpful error messages, so that we can more easily get back on track.

Beyond the standard debugging features in your IDE, Flutter also comes with the Dart DevTools, a whole suite of tools that you can use to monitor and debug your Flutter apps.

The Dart DevTools have been recently rewritten in Flutter, and they can be very useful.

For example, we can use the Flutter Inspector to see the entire widget tree for a running app. We can "select" widgets on screen, and locate them in the widget tree. And it was even announced that a new Layout Explorer will be added, allowing us to see layout errors visually, and fix them:

So I encourage you to check them out, and use them as you debug and profile your apps.

If you're running on VS code, you can find them by opening the command palette and type in devtools.


Flutter offers some great developer tools. But there will still be cases where we get stuck.

And if you're like me, you'll head over to StackOverflow to find some answers.

In this scenario, the ideal situation is that we copy & paste an error message from the debugger, and right away find the correct answer that solves our problem.

However, this doesn't normally happen. Flutter is still a fairly new framework, and there just aren't as many readily available answers, as we would find with more mature technologies.

So chances are that you may have to ask a question for the first time, and wait until someone provides an answer.

Luckily, as Flutter developers we are privileged to have our own super-hero on StackOverflow. His name is Remi, and he has been answering millions of Flutter questions here. I wish to acknowledge all his contributions, and the great value that he brings to the community.


Overall, it is easy to get started with Flutter. But what about taking things further?

Building Complex Apps

As you build more complex apps, you will need to think about state management and app architecture, so that you have a good foundation for your codebase as it grows.

There are multiple state management solutions that you could use, each one with its own pros and cons. This is true not just with Flutter, but also with other major front-end frameworks.

So compared to building UIs and layouts, I feel that state management is a more complex topic.

The official Flutter website only offers a cursory overview of state management, and the "right" solution varies wildly depending on your use case and requirements.

Luckily, state management and other more complex topics are covered in a lot of tutorials by the community.

My video tutorials on state management and the Provider package are a good place to start.

Once you get a good grasp of state management, you can make the most of Flutter when building complex applications.

And what's even better, is that the response time of hot reload is excellent even with big codebases.

Open Source

One of the most strategic aspects of Flutter is that it's entirely open source.

This is great for a lot of different reasons.

Development happens in the open, so you can head over to the Flutter GitHub repo, view the source code, or look for existing issues.

This is easier said than done, because Flutter is a big project with thousands of contributors, and thousands of issues as well.

However this shouldn't be cause of concern. If anything, I find that it just reflects the level of interest and popularity.

I have been using Flutter for nearly two years now. And in experience, the Flutter team has been very responsive in addressing any severe issues in a very timely matter.

As far as the Flutter framework goes, I'm very happy with the turn-around time for critical issues.

And I have not had the same experience with other closed-source SDKs, where there is little transparency in how issues are handled, and progress is much slower.

Flutter has been rock solid since I started using it back when it was in beta, and it is growing quickly.

Official Packages

Flutter comes with many official packages that are not included in the main repository, and these are found in the pub.dev website.

These include things like shared preferences, the image picker, camera streaming APIs, maps support, and the entire suite of Firebase services.

With regards to the official packages, I have to admit that things don't move quite as fast as the main-line Flutter repository. In one case, I had to wait for a few months for some specific Firebase features that I needed in my own projects.

A recent Flutter quarterly survey acknowledged that official packages need to be improved, so I hope to see them evolve in the future.

3rd party Packages

Just in 2019, the wider community has created thousands of new Flutter packages.

This is great because you don't have to reinvent the wheel.

However, I'd like to put a word of caution here.

While the official packages are normally high quality and production ready, the same doesn't always apply to 3rd party ones.

This may be because Dart packages often expose native APIs from the iOS and Android SDKs (via platform channels). And package authors may not always be experienced with both the iOS and Android APIs and their corresponding languages.

This can lead to lower-quality packages, and potentially to bugs in your own apps.

Top Tip: Always be conservative in how many packages you use.

And when you choose packages:

  • you should always check their score
  • whether they are regularly maintained
  • how many issues they have

And if you can't find a well-maintained package that does what you need, DIY can be an option.

Testing

Writing tests gives us confidence that our code works as intended, and we don't introduce bugs and regressions as we make changes.

Flutter offers some great support for testing, in the form of unit, widget and integration tests.

However, the official docs are a bit short on details, and there aren't many tutorials on this topic.

Fear not, as my Flutter course includes two full hours of content on testing alone.

And while testing is great, it's even better when it's automated.

Out of the various Flutter CI systems, I have used both Codemagic and Bitrise, which are mature enough and work very well for automating builds, run tests, and distribute our apps.

Nevercode (the company behind Codemagic) deserves a mention, as they are doing a lot of innovation around the Flutter ecosystem. And they even released Remote Mac, which can be used to develop your Flutter apps for iOS if you're a Windows user.

Performance

This is yet another point in favour of Flutter.

When implemented correctly, Flutter apps exhibit great performance, with smooth scrolling and animations.

This is largely due to the power of the Flutter engine.

This level of performance is unmatched by other cross-platform frameworks, that don't control the rendering pipeline in the way Flutter does.

Should you experience any performance issues, Flutter comes with a great set of tools that you can use to profile your apps.

Maintainer commitment

Flutter is great in many ways. But we should consider some additional aspects before choosing it for long-term projects.

Longevity and maintainer commitment are very important when evaluating a framework.

Google has a track record for sunsetting a lot of their previous projects.

So the big question is: will Flutter share the same fate as some of these dead products?

In this respect, I feel that the opposite is true, because Flutter is very strategic to Google itself. Flutter already runs on iOS, Android, web and desktop, and is the main app development framework for the upcoming Fuchsia operating system.

Beyond that, at Flutter Interact we have been given a glimpse for Google's vision about Flutter, as a portable UI toolkit that will power user experiences across many more devices in the future.


Before we wrap up, I'd like to answer a couple of questions.

  • should teams and businesses use Flutter?
  • where to find Flutter developers?

Should teams and businesses use Flutter?

"Code once, run on multiple platforms" is an attractive proposition for businesses.

Flutter is great, because you can write ll the UI code and your business logic just once in Dart.

And you will only need to write Swift or Kotlin code if you need to call platform-specific APIs that aren't covered by any Dart packages (less and less likely as time goes).

And considering that Flutter has hot-reload and modern declarative APIs, in my experience:

Building an app in Flutter takes 1/3 of the cost and effort needed to build two separate apps on iOS and Android.

Your mileage my vary on this, but Flutter has already been a winner in multiple greenfield projects for me.

The word greenfield is key here. Flutter makes most sense for new projects (or app rewrites).

On the other hand, there are millions of existing apps on the app stores, which are written with the native iOS and Android SDKs. And when it comes to adding Flutter to existing codebases, we need to make additional considerations.

From a technical perspective, the Flutter team has made it possible to add Flutter to existing apps.

But I feel that overall the biggest obstacle is that teams are made of people. Some people may be more comfortable with native SDKs, while others prefer to use Flutter.

Each team and each project are different, so Flutter should be evaluated on a case by case basis.

Finding Talent

Available talent is very important when evaluating a new technology.

In other words, how easy is it to find Flutter developers compared to iOS and Android developers?

iOS and Android have been around for more than 10 years, there are many more developers that are familiar with those SDKs compared to Flutter.

And there are also far more jobs as a native iOS or Android developer. My prediction is that native app development will still be very relevant in the next 5 years.

However, in our industry, change is the only constant. And Flutter is here to stay and grow.

Both Dart and Flutter are easier to learn, compared to less modern native frameworks. And this means that it doesn't take as long to become productive with Flutter.

Product teams that want to use Flutter have two options:

  • hire new Flutter developers, or
  • train their existing app developers to use it

Native iOS and Android development experience is a valuable skill that you're likely to use even if you're building Flutter apps.

But I feel that in the future, Flutter will increasingly win the hearts of developers and businesses.

Summary

And when evaluating a new language or framework, there are a lot a criteria that come into play.

Flutter really shines when it comes to portability, language tooling (around hot reload), and documentation. We can use Flutter to craft beautiful and performant apps that run on a variety of devices.

The community is great and plays a big role in making Flutter more popular.

In my view, the biggest challenges for Flutter are the package ecosystem (which is still young and needs to grow), and the relatively modest job market and availability of Flutter developers.

However, Flutter is growing from strength to strength. And I think this is a great time to learn it.

How to get started

And the best place to start is the Flutter website, which contains documentation, examples and codelabs.

I also recommend the official Flutter channel on YouTube. I learned a lot from the Flutter in Focus and Widget of the week playlists.

And we can quickly try things out with Dartpad.

Beyond that, my entire YouTube channel is all about learning Flutter. I'm regularly adding new tutorials, all conveniently organized by topic with playlists.

And alongside that, I have also created a Flutter & Firebase course on Udemy.

This is a great way to learn with a more structured approach, following a linear progression.

With over 20 hours of content, it shows you how to use Flutter & Firebase to build a complete, production-ready app for iOS & Android.

My students love it. You can check the reviews, and decide for yourself.

You can get the course for a discounted price by using this link:

Brand New Website

By the way, I promised that I had a little secret I wanted to share with you.

And that is that I'll be replacing codingwithflutter.com with a brand new website that is all about learning Flutter.

This will contain all my YouTube videos and articles, and it will be an extensive repository of high-quality Flutter tutorials.

I expect this to be live in January 2020, and it will be completely free to everyone.

So stay tuned on my YouTube channel, and I'll be sharing exciting updates very soon.

Happy coding!

References

In preparing this overview, these articles have inspired me:

Want more? Get my Flutter & Firebase Udemy Course: View Course