I'm learning Flutter, and I'm trying to define a custom color scheme for my app. I'm using ColorScheme.light().copyWith()
, since I only want to override a few colors. I've defined a new primary
color that I wanted my app to have.
However, when I give a widget that primary color by doing Theme.of(context).colorScheme.primary
, it gets the primary color of the default material theme, and not the one I defined.
This is my widget -
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(
fontFamily: 'Poppins',
colorScheme: const ColorScheme.light().copyWith(
primary: const Color(0xFF2DBA4B),
onPrimary: const Color(0xFFFFFFFF),
secondary: const Color(0xFF2DBBA1),
onSecondary: const Color(0xFFFFFFFF),
surface: const Color(0xFFFEF7FF),
surfaceDim: const Color(0xFFE1E1E1),
onSurface: const Color(0xFF1D1B20),
),
),
home: Scaffold(
bottomNavigationBar: Padding(
padding: const EdgeInsets.only(bottom: 15),
child: GNav(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
color: Theme.of(context).colorScheme.secondary,
activeColor: Theme.of(context).colorScheme.onPrimary,
tabBackgroundColor: Theme.of(context).colorScheme.primary,
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 17),
gap: 7,
onTabChange: (index) => navigateBottomBar(index),
tabs: const [
GButton(icon: Icons.home, text: "Home"),
GButton(icon: Icons.monetization_on, text: "Transactions"),
GButton(icon: Icons.auto_graph, text: "Summary"),
GButton(icon: Icons.settings, text: "Settings")
]
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(10),
child: pages[currentPage],
),
),
),
debugShowCheckedModeBanner: false,
);
}
And this is the result I'm getting -
The highlighted button should be the primary color I defined (which is a shade of green), but it is the default primary color in the material light theme.
I have noticed that when I change the onSurface
color, the color of all the text in my app changes, but changing all the other colors has no effect. How can I get this to work?
Take, for example, this line:
color: Theme.of(context).colorScheme.secondary
Notice how it refers to context
and then look up through the build
method and you see that it has captured the context
passed into build
, which is therefore above your MaterialApp
.
To solve this, use the Builder
widget. See: https://api.flutter.dev/flutter/widgets/Builder-class.html
Replace:
home: Scaffold(
with
home: Builder(builder: (BuildContext context) => Scaffold(
// scaffold code as you have now
)
Now, all the references to context
within the scaffold will refer to the builder's context, which is below the material app.