Shared ThemeData between light and dark themes - flutter

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()

Related

Default color scheme Flutter

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.

Getting failed assertion with setting brightness: Brightness.dark for darkTheme

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

migrating accent color in flutter v2.5

after the flutter 2.5 update my theme data kinda broke and doesn't accept accentColor anymore. I took a look at the documantation and saw that is "renamed" to colorScheme.secondary. But no matter what I try, I can't get it to work for me.
This is my current code:
class Themes {
static final lightTheme = ThemeData(
accentColor: Palette.orange,
colorScheme: ColorScheme.light(),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: Palette.orange,
foregroundColor: Colors.white,
),
scaffoldBackgroundColor: Colors.white,
);
static final darkTheme = ThemeData(
accentColor: Palette.orange,
colorScheme: ColorScheme.dark(),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: Palette.orange,
foregroundColor: Colors.white,
),
scaffoldBackgroundColor: Colors.grey[900],
);
}
So many changes are in flutter 2.5
Try to use Below code hope it's helpful to you
theme: ThemeData(
colorScheme: Theme.of(context).colorScheme.copyWith(secondary: Color(accentColor))
),
for more information check official documentation here
final ThemeData theme = ThemeData();
MaterialApp(
theme: theme.copyWith(
colorScheme: theme.colorScheme.copyWith(secondary: myColor),
),
//...
)
Code before migration:
Color myColor = Theme.of(context).accentColor;
Code after migration:
Color myColor = Theme.of(context).colorScheme.secondary;

What's the difference between accessing the text theme via .of(context) method instead of statically?

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

Changing text color for dark mode in Flutter(with Dynamic Theme)?

Text turn to white when I got select dark mode but I want to make all texts white70 or something(including buttons and regular texts). How can I definde the default text color for dark mode?
My Theme data like this right now:
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light,
data: (brightness) => ThemeData(
primarySwatch: Colors.blueGrey,
brightness: brightness,
),
You can do something similar to this (Feel free to change things as you'd like):
At first go to ios/Runner folder. Next open info.plist and add the following lines into the Dict section.
<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
Next. Make sure you have these lines in Theme settings of your MaterialApp:
MaterialApp(
themeMode: ThemeMode.light, // Change it as you want
theme: ThemeData(
primaryColor: Colors.white,
primaryColorBrightness: Brightness.light,
brightness: Brightness.light,
primaryColorDark: Colors.black,
canvasColor: Colors.white,
// next line is important!
appBarTheme: AppBarTheme(brightness: Brightness.light)),
darkTheme: ThemeData(
primaryColor: Colors.black,
primaryColorBrightness: Brightness.dark,
primaryColorLight: Colors.black,
brightness: Brightness.dark,
primaryColorDark: Colors.black,
indicatorColor: Colors.white,
canvasColor: Colors.black,
// next line is important!
appBarTheme: AppBarTheme(brightness: Brightness.dark)),