Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add custom property to ThemeData in Flutter

I need to change color of a widget based on theme. I have separate ThemeData for light and dark theme. Now is it possible to add a custom property to ThemeData so that I can change the color of the widget based on theme and using that custom property?

like image 692
Newaj Avatar asked Jun 18 '20 07:06

Newaj


2 Answers

Sadly, it appears that you simply can't - and the Flutter team doesn't seem to be interested in adding this, given their suggestion.

I think this is a major flaw, because we can't benefit from Theme.of(context) to automatically update all of our Widget that consume this ThemeData.

While some may say that you can use extensions to add new properties, you effectively won't know how to differ between multiple ThemeData (unless you can use some properties like Brightness, but I think this is just too hacky and not reliable to do so).

The alternative is to create another InheritedWidget (just like they said in the issue mentioned above) to handle your custom theme properties.

Edit: It seems that a new PR has introduced the possibility to extend the ThemeData, but it hasn't landed in main or even stable yet.

like image 74
Guilherme Matuella Avatar answered Sep 27 '22 23:09

Guilherme Matuella


Flutter has recenty introduced ThemeExtensions (thanks @guilherme-matuella for the PR link!)

You can get a pretty good idea on how to use the functionality by following examples from the main Flutter repo:

return MaterialApp(
  title: MyApp._title,
  theme: ThemeData.light().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      const MyColors(
        brandColor: Color(0xFF1E88E5),
        danger: Color(0xFFE53935),
      ),
    ],
  ),
  darkTheme: ThemeData.dark().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      const MyColors(
        brandColor: Color(0xFF90CAF9),
        danger: Color(0xFFEF9A9A),
      ),
    ],
  ),
  themeMode: isLightTheme ? ThemeMode.light : ThemeMode.dark,
  home: Home(
    isLightTheme: isLightTheme,
    toggleTheme: toggleTheme,
  ),
);

Which you can later retrieve in your widget like so:
final MyColors myColors = Theme.of(context).extension<MyColors>()!;

like image 41
Nikita Eroshin Avatar answered Sep 27 '22 22:09

Nikita Eroshin