Keeping your Flutter app resilient to change

Marcin Oziemski
Netguru
Published in
4 min readOct 15, 2020

--

This is the story about how I’ve structured the Flutter application so that it can really keep up with customer demands on change.

Photo by Ross Findon on Unsplash

Many developers react allergically when after they implemented something and everything is working how it should, the client is changing mind and suggest the CHANGE.

I think we all know that feeling, for sure I do. I was in that position so many times in a short period of time that the only thing that was protecting my mental health was a couple of good practice I was doing.
Let me share them with you and hopefully help you to not go mad 😅.

Components 🧩

So for sure one of the biggest roles in keeping my sanity was separating and reusing everything I could.
My “widgets” package has around 30 of reusable widgets that are properly styled and used across the whole app.

You could say: “Ok that's all very nice but what exactly do you have there?”.
So I have very simple things like “AppCard” which is just a styled card with specified round corners and elevation, but also “CircleProgressBar” which is a circle with a cutout that shows progress with animation (image below).

There is a lot of widgets that are constructed from smaller ones. For example, AppListItemWithImage which is a component for representing basic list items with an image in my app (because the name was not clear enough 😅) is constructed from the AppCard widget.

That way if for some reason the client would like to change for example the elevation of all cards in your project it will be as simple as changing one value (and I changed it at least 3/4 times).

You could say that the above example with changing elevation could be handled just by having a file with values for dimensions and one particular that could be named something like “cardElevation” and that it is 100% true. I‘m doing it too and it helped me but reusing whole widgets give you a lot more freedom. For example, if one day the client would like that all cards in the app should have corners in the shape of a flower 🌺 then it would be doable with some custom clipper (no that was not my case tho 😁).

Dimensions and Colors

So like I already wrote we can also achieve many good things by just using a reference to common dimensions and colors applied across the app.

Every good designer is working with style guides that have a palette of colors, common dimensions, fonts, and reusable components so that the whole design looks consistent and not like patchwork. The same should be the case in implementing an app. We should write down the whole “style guide” and use it in the app so that the whole project is consistent and changing some parts will be only made in one place.

Dimensions 📐

The dimensions constant I use for everything that could be represented in number. From width and height to elevation and corner radius. If you using any number more than once and it has any logical correlation write it down in dimensions.

Colors 🖌

So for sure you heard about Theme (that will be the next chapter so stop your horses 🏇). In it we usually have a couple of colors that are named “primary”, “secondary”, “background”, etc. and those you all are using const for that, but when it comes to some light grey for that small terms and condition text we should use const too.

For example, when the client would like to add dark mode in the future and that light grey should be a little bit lighter to be visible in both themes it would be easier to change only one const then searching across the whole app of usage name “Color”.

Pro Tip: If you can, push for adding a dark theme from the start of the project. It’s really a small cost of adding it at the begging and it could be a really big one at the end.

Theme ️🦸‍♂️

In the past few lines, I wrote that word a couple of times so what’s there left to say about that?

Actually.. quite a lot 😅. A theme in flutter defines colors for various components but also styles. We can define a couple of them for texts and with that check the last thing that was missing from our “style guide” the fonts.

headline6: GoogleFonts.poppins(
color: AppColors._white,
fontWeight: FontWeight.w700,
fontSize: Dimensions.TITLE_TEXT_SIZE,
),

There is really a lot of text styles you can define and I know that “headline6” could mean nothing to you but the point is to define them. If you do, then you can use it in any place of code by:

Theme.of(context).textTheme.headline6

You are not convinced? That's ok because I don't like this either. We can do better by defining extensions functions on our BuildContext:

extension ThemeGetter on BuildContext {
TextStyle titleStyle() => Theme.of(this).textTheme.headline6;
}

That way calling it would have a lot more meaning and be shorter:

context.titleStyle()

That’s all folks 🙇

I hope that you will survive your next project with a smile 😄 on your face even in a really unstable environment.

If you found this article helpful or just like the article please leave a 👏 .

--

--

Marcin Oziemski
Netguru

Senior Android and Flutter Developer. Working at Netguru.