As a Frontend, Fullstack or even Backend developer I’m sure you must have googled “how to theme…” at least once. With app theming being so common nowadays but still being a bit complicated on most frameworks it’s not a surprise that “how to theme a * app” is commonly searched on google by Frontend to Backend developers alike.
In this article I will be sharing how I go about theming my Flutter apps, whether that be a side project or otherwise, using the ChangeNotifier class.
- Basic Flutter and Dart knowledge
- Flutter SDK fully installed on your development machine
- A device or emulator to test your app
- Basic knowledge on the ChangeNotifier class (Simple app state management | Flutter)
I will be starting out by creating the theme.dart file. It can be kept in any directory depending on your file structure. I keep it in its own separate folder that contains files like colors.dart and any other theming/styling variables.
First things first, let’s change the root of our app into a stateful widget. We need to do this in order for the widget tree to re-render when the theme is changed. Some of you might think that is going to be very tasking process for the app especially if it’s a huge app like Instagram for instance, well you will be surprised to know that Flutter handles this quite well and if you do run into any bottlenecks or janky frames you can always make use of the AnimatedBuilder widget which takes in a Listenable as an argument and changes the children widgets or the widget tree that it wraps based on changes happening within the Listenable .
As I usually do in articles like this I explain the code within the code snippet. Take note of the comments.
We can leave the main.dart file as is for now and move on to creating the Theme.dart file.
In this file we will be declaring our themes whether that be light, dark, sunrise, noon, or whatever you want to call them. We do this by making use of the ThemeData class in Flutter
You can change the colors, text styles and more to whatever your app theme might be. Be careful while using some parameters though, for some reason some won’t work when combined with other parameters. For instance, the bodyMedium and bodyText1 parameters in the TextTheme class can not be used at the same time, this will cause an error that will break the app and show the below error
We will be making a class called AppTheme that makes use of the ChangeNotifier class. This will house our theme state and the callback that will handle toggling of the theme.
In the above code snippet I added the AppTheme class into the theme.dart file. I did this because the class is only a few lines of code. Notice that I created an instance of it on the 30th line, I did this because it would be easier to understand if another person were to take a look at your code and look for the root instance of AppTheme.
I made themeMode a getter since it is ill advised to mutate state directly, since mutating state directly leads to unexpected bugs some times.
Once you’ve created all that you can go back to your main.dart file and implement it in the MaterialApp widget at the root of your application, like so:
And with this you’re done. In order to make use of the themed values all you need to do is use Theme.of(context).* with (*) being the parameters you set in the ThemeData variables earlier e.g(Theme.of(context).textTheme.headlineMedium)
Let me show you the PlaceholderWidget code as an example
Let me show you what your app might look like if you followed this article to the letter:
And voila! You’re all done theming your Flutter app. With less than 30 lines of code and a few changes to already existing code you’ve added theming to your Flutter app.
If this article helped you in any way, please feel free to share, leave a comment or applause 👏. If you think that I could improve the article in any way, please leave a comment, I would be happy to chat and rub minds.
If you really liked this article feel free to check out my other posts on similar topics. And don’t forget to tune in next week for an inside look into a little side project I’m working on.