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:

  1. return new MaterialApp(
  2. title: 'Flutter Demo',
  3. // This is actually redundant.
  4. // Flutter defaults to 'blue' for the ThemeData
  5. theme: new ThemeData(
  6. primarySwatch: Colors.blue,
  7. ),
  8. home: new MyHomePage(title: 'Flutter Demo Home Page'),
  9. );

If you go ahead and take that theme data out, and just stick with thefollowing, you actually get the same thing.

  1. return new MaterialApp(
  2. title: 'Flutter Demo',
  3. home: new MyHomePage(title: 'Flutter Demo Home Page'),
  4. );

Flutter Dark Theme

Flutter also includes a Dark theme.

  1. return new MaterialApp(
  2. title: 'Flutter Demo',
  3. theme: new ThemeData(
  4. brightness: Brightness.dark, // new
  5. ),
  6. home: new MyHomePage(title: 'Flutter Demo Home Page'),
  7. );

Flutter Dark Theme

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).
  • Typography (More detail below)

    • You can set a primaryTextTheme, that will be used by default, and secondaryTextTheme, that you can use to override text where necessary.
  • Icon data

  • Form element themes

    • i.e. inputDecorationTheme, buttonThemeData and sliderThemeData.
  • 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:

  1. Widget build(BuildContext context) {
  2. return new MaterialApp(
  3. title: 'Flutter Demo',
  4. theme: new ThemeData(
  5. primaryColor: Colors.amber,
  6. textTheme: new TextTheme(
  7. body1: new TextStyle(color: Colors.red),
  8. ),
  9. ),
  10. home: new MyHomePage(title: 'Flutter Demo Home Page'),
  11. );
  12. }

Simple theme changes

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.

  1. // The `copyWith` method over writes only what you want to overwrite.
  2. textTheme: Theme.of(context).textTheme.copyWith(
  3. body1: new TextStyle(color: Colors.red),
  4. ),
  5. ...

Simple theme changes with copyWith

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:

  1. ...
  2. theme: Theme.of(context).copyWith(
  3. primaryColor: Colors.amber,
  4. textTheme: Theme.of(context).textTheme.copyWith(
  5. body1: new TextStyle(color: Colors.red),
  6. body2: new TextStyle(color: Colors.pink, fontSize: 24.0), // new
  7. ),
  8. ),
  9. ...

In order to use that body2 style in an app, use the of method that'sprovided on Theme:

  1. new Text(
  2. 'You have pushed the button this many times:',
  3. style: Theme.of(context).textTheme.body2),
  4. ),

Theme changes 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.

  1. theme: Theme.of(context).copyWith(
  2. primaryColor: Colors.amber,
  3. textTheme: Typography().black, // new
  4. ),

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.