'Flutter: Add custom color to existing theme

I am using Flutters built-in themes like this:

 return MaterialApp(
          theme: ThemeData.light().copyWith(
            primaryColor: const Color(0xFF5E975A),
            bottomAppBarColor: const Color(0xff282828),
            // ... And so on
          ),

As you can see I am modifying the existing theme with copyWith. Now let's say I want a certain button to always have the Color(0xFFFF0000). Is there a way to add a new key to the existing theme?

Something like this:

ThemeData.light().copyWith(
            ...
          ).addKey(myCustomColor: const Color(0xFFFF0000))

If not, what is the best-practice way to define my custom color? I feel like just declaring a global static variable is not the intended way to implement this.



Solution 1:[1]

I am still finding the best practice way of defining ThemeData. For now, I have already used 2 ways to achieve the custom colors:

1 Use Extension

// use it with "Theme.of(context).myCustomColor"
extension CustomThemeDataExt on ThemeData {
  Color get myCustomColor {
    if(brightness == Brightness.light){
      return Color(0xFFFF0000);
    } else {
      ...
    }
  }
  ...
}

...

2 Define a custom theme

// use it with "CustomTheme.of(context).myCustomColor"
class CustomTheme {
  final BuildContext context;

  const CustomTheme(this.context);

  static CustomTheme of(BuildContext context) => CustomTheme(context);

  Color get myCustomColor {
    if(Theme.of(context).brightness == Brightness.light){
      return Color(0xFFFF0000);
    } else {
      ...
    }
  }
}

Both need to import the relative file.

Solution 2:[2]

Update for Flutter 3:

Flutter has answered this exact question in the newest version of Flutter. You can now create ThemeExtensions.

This can look something like this (after defining your ThemeExtension):

MaterialApp(
  theme: ThemeData.light().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      CustomColors.light,
    ],
  ),
  darkTheme: ThemeData.dark().copyWith(
    extensions: <ThemeExtension<dynamic>>[
      CustomColors.dark,
    ],
  ),
  // other parameters...
);

In the future there will be definitely more information about this but for now have a look at this article. I took the sample from there.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 yellowgray
Solution 2 Josip Domazet