Flutter Theme Class
Effectively using ThemeData will potentially save you from having to ever thing about colors, typography and global styles. It's truly set it and forget it.
In Flutter, everything is a widget. Because of that, styling and UI inFlutter is handled similarly to component-based, scoped CSS on the web (a laVue or Styled Components). This is definitely a feature, and a huge wine forstyling. But, Flutter also gives you some handy ways to set global stylesettings. Mostly via the built in Theme
widget.
Theme
is an inherited widget that you more or less use to set things likeColor and Font, and it automatically applies these settings to all widgetsbelow it in the Widget tree.
MaterialApp
Widgets are the only widgets that accept aTheme. These Widgets will always be at the top of a Widget tree. For allintents and purposes, when you set ThemeData
, it sets properties in yourentire app.
Example One: Default Theme
Particularly using the MaterialApp
as your root widget (which I imagineyou'll be doing almost always), there's a default Theme
, that if you don'toverride, sets up your app with a general Material style look.
Consider the starting counter app that s built when you start a new Flutterproject. This is in the MyApp
widget:
return new MaterialApp(
title: 'Flutter Demo',
// This is actually redundant.
// Flutter defaults to 'blue' for the ThemeData
theme: new ThemeData(
primarySwatch: Colors.blue,
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
If you go ahead and take that theme data out, and just stick with thefollowing, you actually get the same thing.
return new MaterialApp(
title: 'Flutter Demo',
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
Flutter Dark Theme
Flutter also includes a Dark theme.
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
brightness: Brightness.dark, // new
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
Setting Theme Data
There a boatload of changes you can make. Here's the full list.
The changes roughly fall into the following categories:
Colors
- These properties range from very broad (
primaryColor
) to very specific (secondaryHeaderColor
).
- These properties range from very broad (
Typography (More detail below)
- You can set a
primaryTextTheme
, that will be used by default, andsecondaryTextTheme
, that you can use to override text where necessary.
- You can set a
Icon data
Form element themes
- i.e.
inputDecorationTheme
,buttonThemeData
andsliderThemeData
.
- i.e.
Target platform (More on this below.)
- This is actually a property that you wouldn't set, but rather use as a getter.
Simple example changes:
Widget build(BuildContext context) {
return new MaterialApp(
title: 'Flutter Demo',
theme: new ThemeData(
primaryColor: Colors.amber,
textTheme: new TextTheme(
body1: new TextStyle(color: Colors.red),
),
),
home: new MyHomePage(title: 'Flutter Demo Home Page'),
);
}
Build A Theme Effectively
You may have noticed an issue here. The text that displays the current countis white and unreadable. This is because my code completely overrode thetheme by establishing a new Theme. You can aovid this by just overwriting thetheme data you want to overwrite.
// The `copyWith` method over writes only what you want to overwrite.
textTheme: Theme.of(context).textTheme.copyWith(
body1: new TextStyle(color: Colors.red),
),
...
The best way to build a theme is start with the default built intoMaterialApp
, and use copyWith
for all the new information.
Get ThemeData in your App
I added this to my apps theme:
...
theme: Theme.of(context).copyWith(
primaryColor: Colors.amber,
textTheme: Theme.of(context).textTheme.copyWith(
body1: new TextStyle(color: Colors.red),
body2: new TextStyle(color: Colors.pink, fontSize: 24.0), // new
),
),
...
In order to use that body2
style in an app, use the of
method that'sprovided on Theme:
new Text(
'You have pushed the button this many times:',
style: Theme.of(context).textTheme.body2),
),
That's all there is to it.
TextTheme
TextThemes are essentially exactly the same, but taking the time to set upthe text themes you want at the beginning will save you a lot of time later.These are the properties you can set with your TextTheme:
- display4
- display3
- display2
- display1
- headline
- title
- subhead
- body2
- body1
- caption
- button
To be honest, no app in the world should need more than that many differentfont styles. Consistency is the first key to good app design.
Typography class
Flutter also has a handy built in class called Typography
. This class hastwo properties: Tyopgraphy.white
and Typography.black
. This class simplyprovides text that follows Material design guidelines.
theme: Theme.of(context).copyWith(
primaryColor: Colors.amber,
textTheme: Typography().black, // new
),
This class cannot be overridden.
Your default text theme will already follow these guidelines, so you probablywon't find yourself using this, ever. In fact, I think the point is thatthis is the starting point for all your textThemes.
NB: If using default text themes, the text will change between theproper text themes depending on the device: Cupertino for iOS andMountainView for Android and Fuchsia. However, while testing, your appwill always display MountainView.
Custom Themes
In the next lesson, you'll see how you can use the InheritedWidget
to buildyour own custom theme.