rydmike / flex_color_scheme

A Flutter package to make and use beautiful color scheme based themes.
Other
947 stars 105 forks source link

Can't change fontFamily using copyWith() #171

Closed GitGud31 closed 1 year ago

GitGud31 commented 1 year ago

I'm trying to set different FamilyFonts for different Locales, when I try to use the lightFlexTheme.copyWith(fontFamily: desiredFont) I get an error that says 'fontFamily' is not defined.

image

theme: lightFlexTheme.copyWith(fontFamily: fontFamily)
final lightFlexTheme = FlexThemeData.light(
  colors: const FlexSchemeColor(
    primary: Color(0xff2e7d32),
    primaryContainer: Color(0xffa5d6a7),
    secondary: Color(0xff00695c),
    secondaryContainer: Color(0xff7dcec4),
    tertiary: Color(0xff004d40),
    tertiaryContainer: Color(0xff59b1a1),
    appBarColor: Color(0xff7dcec4),
    error: Color(0xffb00020),
  ),
  surfaceMode: FlexSurfaceMode.highScaffoldLowSurface,
  blendLevel: 20,
  appBarStyle: FlexAppBarStyle.background,
  appBarOpacity: 0.95,
  subThemesData: const FlexSubThemesData(
    elevatedButtonSchemeColor: SchemeColor.surfaceTint,
    elevatedButtonSecondarySchemeColor: SchemeColor.primaryContainer,
    elevatedButtonRadius: 5.0,
    blendOnLevel: 20,
    blendOnColors: false,
  ),
  visualDensity: FlexColorScheme.comfortablePlatformDensity,
  useMaterial3: true,
  fontFamily: GoogleFonts.montserrat().fontFamily,
);

am I not using it correctly ? is there a workaround for this ?

rydmike commented 1 year ago

Hi @GitGud31,

Thanks for your question. It is a good one and fontFamily can indeed be confusing. Let me try to explain why.

The observation and analyzer is of course correct, and even expected. There is no fontFamily property in your lightFlexTheme since it is a ThemeData object.

The line:

final lightFlexTheme = FlexThemeData.light(..);

Returns a ThemeData object and ThemeData object does not have a property fontFamily. This is a feature of Flutter SDK, not FlexColorScheme.

This can feel confusing, since the ThemeData() factory has a ´fontFamilyparameter (and for convenience, so doesFlexThemeDataor actually theFlexColorSchemeclass it uses), but the producedThemeDataobject does not have one. I don't know why the Flutter SDK chose to implement a factory that looks like a default unnamed object constructor and name the actual object constructor underThemeData.raw()`. It is certainly confusing.

The ThemeData() factory, much like FlexColorScheme and its different ThemeData() factories are basically just like a function that does its own logic to construct and return a ThemeData object.

In the ThemeData() factory, fontFamily is a convenience parameter that can be used to easily configure the two TextTheme objects textTheme and primaryTextTheme that are the actual properties in a ThemeData object. When the ThemeData object has been constructed, there is no longer a fontFamily property in the actual ThemeData object, only the actual properties it was used for, as a helper, to make.

In the resulting ThemeData, on the properties textTheme and primaryTextTheme you can operate with copyWith on ThemeData, to modify them.

Be aware that there are many caveats when working with TextTheme in ThemeData, even more so when using a GoogleFonts textTheme. However, FlexColorScheme does contain a "fix" for making using GoogleFonts default constructed TextThemes, like e.g. GoogleFonts.montserrat() easier and work more as expected, but that does not apply to copyWith on ThemeData.

I suggest reading this Q&A answer to get up to speed on most of the TextTheme and GoogleFonts caveats:

https://github.com/rydmike/flex_color_scheme/discussions/160#discussioncomment-5999257

Hope this helps 😄 and happy theming!

BR Mike

PS. Converting this issue to a Q/A question as well. Maybe it will help others some day too if they find it there.