Style Your App with Themes
Learn how to use themes to style your apps and switch styling based on whether the underlying OS is set to dark mode.
Themes are used to share color, font and design styles in your apps. By default, Flutter provides us with a default theme when we use the MaterialApp. This theme has the light and dark version. Currently, it is set to the light theme. It has a primary color of blue as seen in the AppBar, BottomNavigation bar and the FloatingActionButton.
To see the dark version update the
MaterialApp to the following:
... theme: ThemeData.light(), darkTheme: ThemeData.dark(), themeMode: ThemeMode.dark, ...
And our app updates to the default dark theme provided by Flutter. Let’s talk about the settings we just added. In here, we set the
darkTheme properties to use the default light and dark theme provided by the MaterialApp. The
ThemeData class defines colors and fonts and the overall styling of a MaterialApp or a widget and its descendants.
themeMode is set to
ThemeMode is an enum used to hold different theme modes. Here, we set it to use the dark mode by default. The default is
ThemeMode.system which sets the theme based on the user’s device settings. Dark mode setting is available in Android 10 and iOS 13 devices and up. Let me show you how our app adapts to this.
First, comment out the theme mode since the default mode takes the device settings. And then head over to your device settings. Select Display. And enable dark mode by selecting dark theme. For iOS devices, the dark mode settings is located in the “Display & Brightness” settings. Cool, now let’s head back to our app. And you can see, our app now uses its dartk theme.
ThemeMode value can be toggled and managed as a feauture in your app but that’s beyond the scope of this course. I’ll go ahead and switch off dark mode is the settings. Go ahead and do that too.
Now that we have our app back to its original form, let’s explore more features of a theme. To change the default light theme. Update your code to the following:
final lightTheme = ThemeData(); ... theme: lightTheme.copyWith( colorScheme: lightTheme.colorScheme.copyWith( primary: Colors.red, secondary: Colors.green, ), ), ...
Save your work. This sets the primary color to red and the secondary color to green. You can see the appbar takes the primary color and the FAB takes the secondary color. The
ThemeData class also give you access to create themes specific to widgets like the appbar, text, cards, FloatingActionButtons and others.
And if you noticed, we declared a lightTheme variable to hold the
ThemeData. We then used the
copyWIth method to extend it and update the settings we want to change. This could be useful when we dont want to override the entire theme. Instead, we want the theme to have its original styling while we just change the parts we want. We can also change general styling in the lightTheme variable we just created.
Let’s focus on the text for the lightTheme for now. You can always do the same for the darkTheme. We style the text with the
textTheme property. Add the following code inside the
textTheme: TextTheme( headline5: TextStyle(fontSize: 24), ),
This add font styling for all the headline5 text in our app. Note: the font size of the healdine5 text is 24 by default, i just added it here for demonstration purposes. To use this, go to the
article_card.dart file. Update the
ArticleCard’s title to use this theme.
Save your work.
And you can see the text still retains the font size, but now, it gets it from the theme. We use the
Theme.of() method to access the theme. This is a static member of the
Theme class that is used to get access to the closest
Theme above it in the widget tree. In this case, it would be the
ThemeData we just defined in the
MaterialApp. With this setup, we can update our
headline5 text to a different
fontSize and the update would reflect in our entire app.
You can adapt a text style without having to write a new style. For instance, you want a headline text to have a different color or fontSize. For this, you use the
copyWith method of the
TextStyle class. This let’s you extend the parent theme.
ArticleCard’s title text to the following:
style: Theme.of(context).textTheme.headline5.copyWith( fontStyle: FontStyle.italic, color: Colors.grey, ),
This copies the original headline5 styling and adds a different color and italicizes the text. We would be using more of the text theming in the next episode where we create the detail page. So you’ll get to appretiate its benefits. I’ll go ahead and comment this out.
Finally, let’s add a custom font for our app. We’ll be using the Lato font from Google. Open up the
pubspec.yaml file. Scroll to the end. I have added the fonts section and specified the font files as assets of our app. Go ahead and add it up if you haven’t. And over here, i specified the bold and italic font file and added the corresponding settings for both the weight and style. This is the actual path to where i stored the files in our project and you can see it inside the assets folder.
To use this add this font as the font family for the app. Head over to
main.dart and add the following line to theme variable:
Note, this is going to change the font family for just the lightTheme. Now, if we try to add a fontFamily to ThemeDat.dark() it complains that is doesnt have that property. To solve this, update your code to the following:
final darkTheme = ThemeData( brightness: Brightness.dark, ); ... darkTheme: darkTheme
Behind the scenes, what the ThemeData.dark() actually does is return a
ThemeData that sets the brightness to
And that’s what we did here. And now, we can set other properties of the
ThemeData since we have direct access to it.
Save your work. And do a hot restart. And there you go: Your app updates to use the Lato font.