I'm getting this error:
'package:flutter/src/material/theme_data.dart': Failed assertion: line 412 pos 12: 'colorScheme?.brightness == null || brightness == null || colorScheme!.brightness == brightness': is not true.
I've used this brightness: Brightness.dark parameter for my dark mode without any problems until a recent update. I updated several things at once, so I'm not sure what caused the change.
Do I need to be setting up my dark mode differently now?
Current dark theme:
darkTheme: ThemeData(
toggleableActiveColor: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
textTheme: _textTheme(),
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.blue).copyWith(secondary: Colors.blueAccent),
brightness: Brightness.dark,
),
This is a consequence of tightening up the ThemeData constructor wrt the brightness parameter and the ColorScheme's brightness parameter in an update of Flutter. In your example the brightness of the ColorScheme is light (the default), but the ThemeData's brightness is dark.
To get your darkTheme working, you need to remove the brightness parameter and put that in the colorScheme, like so:
darkTheme: ThemeData(
toggleableActiveColor: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.blue)
.copyWith(
secondary: Colors.blueAccent, brightness: Brightness.dark),
),
Just Add the brightness property in fromSwatch Constructor
in Dark Theme
colorScheme: ColorScheme.fromSwatch().copyWith(secondary: Colors.blue,
brightness: Brightness.dark)
in Light Theme
brightness: Brightness.light
Related
In this tutorial author show how to prepare new ColorScheme:
const ColorScheme _customColorScheme = ColorScheme(
primary: customMagenta50,
primaryVariant: customMagenta600,
secondary: Colors.amber,
secondaryVariant: customMagenta400,
surface: Colors.purpleAccent,
background: customSurfaceWhite,
error: customMagenta900,
onPrimary: Colors.red,
onSecondary: Colors.deepOrange,
onSurface: customMagenta300,
onBackground: customMagenta100,
onError: Colors.redAccent,
brightness: Brightness.light,
);
A lot of parameters are required in this constructor. Where I can find default colours used in default light theme? I want use code as above and change only one or two values (another values I change at next phase of my project).
You can apply changes to the default light ColorScheme like so:
final ColorScheme _colorScheme = ColorScheme.light().copyWith(->your changes<-);
You can check the source-code on GitHub. For default light colorSchema
You can use copyWith constructor.
return MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
colorScheme: Theme.of(context).colorScheme.copyWith(
//..here
)
),
An easy way to find attributes by pressing ctrl+space while you are inside the copyWith(..here.) method
You can find more details on flutter.dev > ColorScheme.
I'm trying to avoid repeating my code.
My app has light and dark theme modes, and I'm trying to change my app theme in both modes without repeating lines, like the following code.
return MaterialApp(
theme: ThemeData(
primarySwatch: Colors.blue,
// shared ThemeData between light and dark themes :(
appBarTheme: const AppBarTheme(
toolbarHeight: 100,
),
),
darkTheme: ThemeData(
brightness: Brightness.dark,
// shared ThemeData between light and dark themes :(
appBarTheme: const AppBarTheme(
toolbarHeight: 100,
),
),
themeMode: ThemeMode.dark,
);
As I explained in my code, that there are few lines repeated in both light and dark themedata
// shared ThemeData between light and dark themes :(
appBarTheme: const AppBarTheme(
toolbarHeight: 100,
),
Is there a good and TESTED way to avoid this mistake?
First define your ThemeData as a variable, for example:
final myTheme = ThemeData(
// brightness: Brightness.light,
primarySwatch: Colors.red,
primaryColor: Colors.blue,
cardColor: Color(0xCCF2F2F2),
);
You can then use your variable. If you want to modify a few items, you can use the copyWith constructor. For example:
MaterialApp(
// light theme: use the variable as is
theme: themeData,
// dark theme: need to modify a few things
darkTheme: themeData.copyWith(
brightness: Brightness.dark, // change brightness
),
home: MyHomePage(),
)
make a ThemeData variable and put all the shared properties then use copyWith when you want to change something like this:
ThemeData _themeData = ThemeData(
primarySwatch: Colors.indigo,
appBarTheme: AppBarTheme(
color : Colors.deepOrange,
),
);
then :
theme: _themeData.copyWith(
brightness: Brightness.light,
),
darkTheme: _themeData.copyWith(
brightness: Brightness.dark
),
themeMode: ThemeMode.light,
you can also use ThemeData.from()
In flutter even when I set
primaryColor: Colors.orange,
then in some part of the UI the default Colors.blue is still present.
Is there a way how to globally override it for the ThemeData?
In order for me to override Colors.blue, I had to state primarySwatch in the ThemeData and also the colorScheme, as in
theme: ThemeData(
primarySwatch: Colors.orange,
colorScheme: ColorScheme.fromSwatch(primarySwatch: Colors.orange),
),
Try:
primarySwatch: Colors.orange
In Flutter we can write our ThemeData in two ways,
1: As variable
2: As a method
final lightThemeData = ThemeData(
brightness: Brightness.light,
primaryColor: primaryColor,
textTheme: GoogleFonts.poppinsTextTheme(
ThemeData.light().textTheme,
),
elevatedButtonTheme: elevatedButtonThemeData,
colorScheme: ThemeData.light()
.colorScheme
.copyWith(secondary: secondaryColorLightTheme),
);
ThemeData buildThemeData(BuildContext context) {
return ThemeData(
brightness: Brightness.light,
primaryColor: primaryColor,
textTheme: GoogleFonts.poppinsTextTheme(
Theme.of(context).textTheme,
),
elevatedButtonTheme: elevatedButtonThemeData,
colorScheme: Theme.of(context)
.colorScheme
.copyWith(secondary: secondaryColorLightTheme),
);
}
Check the image for more clear explanation
There is no better way here since the two snippets have different behaviors:
In the first one, the theme is independent from where it's used.
In the second snippet, the theme inherits from the ambient theme because of the Theme.of(context).
But the context variant is significantly better
Because with the "create a new theme" variant, there's no single source of truth for the theme. Theming is all over the place
I have two differents flavors with differents styles, and Im trying to init MaterialApp copying this theme and change the brightness to dark or light depending of the settings states, but seems thaht copyWith is not working properly, because the brightness does not changes.
Here is the code:
return MaterialApp(
theme: FlavorConfig.instance.theme.copyWith(
brightness:
Provider.of<SettingsViewModel>(context).darkModeEnabled
? Brightness.dark
: Brightness.light,
),
Any idea?
Try the cupertinoOverrideTheme attribute of the Theme white the copyWith
Something like:
return MaterialApp(
theme: FlavorConfig.instance.theme.copyWith(
brightness:
Provider.of<SettingsViewModel>(context).darkModeEnabled
? Brightness.dark
: Brightness.light,
cupertinoOverrideTheme: FlavorConfig.instance.theme.cupertinoThemeData.copyWith(
brightness: Provider.of<SettingsViewModel>(context).darkModeEnabled
? Brightness.dark
: Brightness.light,
),
),