The New Way to create Themes in your App
CONST values that you can change
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:
- A new BDD Tool for TypeScript/React and Flutter/Dart
- Async Redux: Flutter’s non-boilerplate version of Redux
- Mind-blowing Easy Translations and Internationalization for Flutter
- Announcing FIC: Fast Immutable Collections
- The New Way to create Themes in your Flutter App
Layout packages I’ve authored:
Other Flutter packages I’ve authored:
- async_redux → Redux state management
- i18n_extension → Translate your apps
- fast_immutable_collections → Immutable List, Set, Map
- themed → Set colors and fonts in your app
- provider_for_redux → Use Provider with Redux
- bdd_framework → Test your app
- image_pixels → Access pixels and size of images
- network_to_file_image → Download images and save them to the device
- matrix4_transform → Math package for transforming images
- back_button_interceptor → Android back button
- indexed_list_view → Scroll to specific items in an infinite list-view
- animated_size_and_fade → Fade/Size transition between widgets
- weak_map → Memory management
https://github.com/marcglasberg
https://twitter.com/GlasbergMarcelo