5 lessons learned while working on a complex Flutter application

I’ve spent the last 3 months being the sole developer for a fairly complex Flutter app for a client. It’s been very fun and Flutter is, generally, a pleasure to code with.

It’s also been a learning experience, so I’ve compiled a list of the 5 most important lessons (for me).

Split your stateful widgets

Often, we refactor classes when a file gets big, and that’s fine. But there is another reason to split a stateful widget in Flutter. Remember that the whole widget rebuilds when your code calls setState()? So split your widgets between their static and dynamic content, separate widgets if they contain 2 visual parts that obtain their data separately etc

Example: I had a stack of images, inside a list, and some of the images contained animations. With a simple logic, all the stack code fitted in under 100 LOC in one widget. However, scrolling was a bit jerky. I improved it by creating a widget for each image, and animating those as and when required, instead of rebuilding the whole stack.

Update 29/06/18: I’ve simplified and turned the example above into a code tutorial Improve your Flutter app performance: split your widgets

Handle errors properly in your Futures

I wrote a code tutorial on writing async code in Flutter, so I won’t repeat myself here, except to say one more time “Don’t forget to handle errors!”.

Example: the app uses Firebase plugins for the backend. Sometimes, the whole app froze on start up. It turned out that I was trying to get a value for a key that didn’t exist in a document in the database. A silly mistake which triggered an app freeze instead of an app crash, and took longer than it should have to track down.

Don’t let your print statements crash your app

While working on new code, I often litter it with print statements, so if it doesn’t work  as expected when I run it, I can find out from the logs why. Well, sometimes, the print statements were the reason for the problem!

It turns out that print("Step 1" + expectedStringInstance.toString())  will run fine if expectedStringInstance is null but print("Step 1" + expectedStringInstance) will throw an ArgumentError exception.

As a Java developer, it’s one of the few counter intuitive things I have found in Dart and I keep being caught out! (I’m guessing it is because null is an instance of the class Null)

Choose one architecture and apply it everywhere

I chose MVP but it doesn’t really matter what you choose. What is important is to understand it and apply it everywhere, even on very simple features. Why? Because no doubt those simple features will become more complex and if you don’t have the architecture in place, you will risk writing spaghetti code.

This is true for all frameworks, but especially important when part of your cognitive energy goes into figuring out how to do more basic things with the framework.

Know your multiple children layout widgets

You have probably come across ListView and GridView in tutorials. But I found Row, Column, and Stack (in particular with Positioned) equally important to master.

I’ve written a code tutorial on mastering Row and Column. As for Stack and Positioned, have a look at the second example in my How to overlay text and icon on an image tutorial.

 

Enjoying this article? Support the blog!

Support options
 

What next?

One of the best ways to learn Flutter is to write a large app using it. You can check jobs out on my Flutter job board, or create your own app project. Need inspiration? Have a look at this list of public APIs.

 

 

Subscribe to my mailing list

Receive a monthly email with a curated list of the best 5 articles on software development I have come across during the month, as well as relevant blog updates such as new posts. The email is sent near the start of each month.
* indicates required

Android app developer with 8 years experience, ranging from start ups to large tech (Google) and non tech (British Airways) companies. Currently freelancing and learning Flutter. LinkedIn natalie ( at ) cogitas (dot) net

Author: Natalie Masse Hooper

Android app developer with 8 years experience, ranging from start ups to large tech (Google) and non tech (British Airways) companies. Currently freelancing and learning Flutter. LinkedIn natalie ( at ) cogitas (dot) net

3 thoughts on “5 lessons learned while working on a complex Flutter application”

  1. Even better is:

    print(“Step 1 $expectedStringInstance”);

    …or, even better still:

    debugPrint(“Step 1 $expectedStringInstance”);

  2. Very helpful article. I was particularly interested in your experience with improving the performance of your app by splitting your widgets. Perhaps an idea for a future post could be some code example of how you did this? Perhaps showing the non-performant code against the improved code? Just and idea, but I would find that really useful. Thanks.

    1. Thanks for your feedback. I do have a draft post in progress for this. Well, I still have to write most of it but I will hopefully be able to publish it this month.

Leave a Reply

Your email address will not be published. Required fields are marked *