The New Way to create Themes in your App

CONST values that you can change

Marcelo Glasberg
Flutter Community
4 min readJul 28, 2021

--

I’m always interested in creating packages to reduce boilerplate. For example, i18n_extension package is about translations without boilerplate, async_redux is about Redux without boilerplate, and align_positioned is about layouts with less widgets.

In this article I talk about the Themed package, which is about non-boilerplate themes.

As we all know, using const variables is the easiest way to create and use themes:

static const myColor = Colors.white; 
static const myStyle = TextStyle(fontSize: 16);
Container(
color: myColor,
child: const Text('Hi', style: myStyle)))

However, if you do it like that you can’t later change the theme dynamically. By using the Themed package you can:

static const myColor = ColorRef(Colors.white); 
static const myStyle = TextStyleRef(TextStyle(fontSize: 16));
Container(
color: myColor,
child: const Text('Hi', style: myStyle)))

// Later, change the theme.
Themed.currentTheme = {
myColor: Colors.blue,
myStyle: TextStyle(fontSize: 20);
}

There is no need to use Theme.of(context) anymore:

// So old-fashioned. 
Container(
color: Theme.of(context).primary,
child: Text('Hi', style: TextStyle(color: Theme.of(context).secondary)))

Also, since Theme.of needs the context and is not constant, you can't use it in constructors. However, the themed package has no such limitations:

// The const color is the default value of an optional parameter.
MyWidget({
this.color = myColor,
});

Setup

Wrap your widget tree with the Themed widget, above the MaterialApp:

Widget build(BuildContext context) {
return Themed(
child: MaterialApp(
...

At any moment you can just change the current theme:

// Setting a theme:
Themed.currentTheme = theme1;
// Setting another theme:
Themed.currentTheme = theme2;
// Removing the current theme (falling back to the default theme):
Themed.clearCurrentTheme();

Compatibility

The Themed package is a competitor to writing Theme.of(context).xxx in your build methods, but it’s not a competitor to Flutter’s native theme system and the Theme widget. It’s there to solve a different problem, and it’s usually used together with the Theme Widget. For example, if you want to set a global default color for all buttons, you’ll use the Theme widget. You may use it together with the Themed package, meaning that Themed colors and styles may be used inside a ThemeData widget:

static const myColor1 = ColorRef(Colors.red);
static const myColor2 = ColorRef(Colors.blue);
...
child: MaterialApp(
theme: ThemeData(
primaryColor: myColor1,
elevatedButtonTheme:
ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(primary: myColor2),
), ...

Organization

You can organize your theme in a class:

class MyTheme {
static const myColor = ColorRef(Colors.white);
static const myStyle = TextStyleRef(TextStyle(fontSize: 16);
}
Container(
color: MyTheme.myColor,
child: const Text('Hello', style: MyTheme.myStyle)))

Advanced Features

TextStyle extension

The Themed package comes with an extension that lets you add text styles and colors. For example:

const myStyle = TextStyle(...);// Using some style
Text('Hello', style: myStyle);
// Making text black
Text('Hello', style: MyStyle + Colors.black);
// Changing some other stuff
Text('Hello', style: myStyle + FontWeight.w900 + FontSize(20.0) + TextHeight(1.2));

Color transform

Instead of changing the current theme you can create a color transformation. For example, this will turn your theme into shades of grey:

static Color shadesOfGreyTransform(Color color) {
int average = (color.red + color.green + color.blue) ~/ 3;
return Color.fromARGB(color.alpha, average, average, average);
}
// Use it:
Themed.transformColor = shadesOfGreyTransform;
// Then, later, turn it off:
Themed.clearTransformColor();

TextStyle transform

You can also create a style transformation. For example, this will make your fonts larger:

static TextStyle largerText(TextStyle textStyle) =>
textStyle.copyWith(fontSize: textStyle.fontSize! * 1.5);
// Use it:
Themed.transformTextStyle = largerText;
// Then, later, turn it off:
Themed.clearTransformTextStyle();

This was just a quick look into the themed package. Head to the package documentation for the important details.

Copyright

This package is copyrighted and brought to you by Parkside Technologies, a company which is simplifying global access to US stocks.

This package is published here with permission.

Please, see the license page for more information.

Read more from me:

Layout packages I’ve authored:

Other Flutter packages I’ve authored:

https://github.com/marcglasberg

https://twitter.com/GlasbergMarcelo

https://stackoverflow.com/users/3411681/marcg

https://glasberg.dev

--

--