Primary color declared in colorScheme and ThemeData in Flutter

Viewed 3735

I was following the Material Design components and at the bottom, there was a Theming section for every component.

Here's the ThemeData code,

final ThemeData base = ThemeData.light();
return base.copyWith(
  colorScheme: _shrineColorScheme, 
  toggleableActiveColor: shrinePink400,
  accentColor: shrineBrown900,
  primaryColor: shrinePink100,  //defines primary
  buttonColor: shrinePink100,
  scaffoldBackgroundColor: shrineBackgroundWhite,
  cardColor: shrineBackgroundWhite,
  textSelectionColor: shrinePink100,
  errorColor: shrineErrorRed,
  primaryIconTheme: _customIconTheme(base.iconTheme),
  textTheme: _buildShrineTextTheme(base.textTheme),
  primaryTextTheme: _buildShrineTextTheme(base.primaryTextTheme),
  accentTextTheme: _buildShrineTextTheme(base.accentTextTheme),
  iconTheme: _customIconTheme(base.iconTheme),
);
}

Here's the definition of the ColorScheme,

const ColorScheme _shrineColorScheme = ColorScheme(
 primary: shrinePink400,  //defines primary
 primaryVariant: shrineBrown900,
 secondary: shrinePink50,
 secondaryVariant: shrineBrown900,
 surface: shrineSurfaceWhite,
 background: shrineBackgroundWhite,
 error: shrineErrorRed,
 onPrimary: shrineBrown900,
 onSecondary: shrineBrown900,
 onSurface: shrineBrown900,
 onBackground: shrineBrown900,
 onError: shrineSurfaceWhite,
 brightness: Brightness.light,
);

Here the value of the primary color is set twice. Why is that? We already defined primary in the ColorScheme so why bother doing it in ThemeData.

2 Answers

Although they have the exact same name, but they are in two different classes, basically there are two classes, ThemeData and ColorScheme. ThemeData is one holding all of your theme settings, and the one controlling how the app will look, but ColorScheme is just a set of colors that you create to easily maintain the app's colors. Notice that ThemeData class has a parameter colorScheme, so you can create your own colorScheme and add it to the ThemeData object.

the primaryColor in ThemeData is the primary color for all your application, and you can access it through this line:

Theme.of(context).primaryColor

the primary in ColorScheme, is just the primaryColor for that colorScheme object, and you can also access it by using that line:

Theme.of(context).colorScheme.primary

Note

all of widgets styling inherits from colors or themes from ThemeData (defined in MaterialApp) not ColorScheme, colorScheme is just extra colors that you define to use whether in ThemeData or anywhere across the app.

so colorScheme will only affect widgets colors only if you use these colors in ThemeData, like this:

final ThemeData base = ThemeData.light();
return base.copyWith(
  colorScheme: _shrineColorScheme, 
  accentColor: _shrineColorScheme.secondary,
  primaryColor: _shrineColorScheme.primary, 
  scaffoldBackgroundColor: _shrineColorScheme.background,
);
}

A comment in the ThemeData object provides some clarity:

[colorScheme] is the preferred way to configure colors. The other color properties (as well as primaryColorBrightness, and primarySwatch) will gradually be phased out, see https://github.com/flutter/flutter/issues/91772.

So for now, I'd recommend setting the colorScheme property using your ColorScheme object and then referencing the values in that object in the ThemeData properties, like primaryColor, focusColor, etc.

Related