flutterflutter-theme

Custom ColorScheme.primary color doesn't show up in Flutter app


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 -
enter image description here

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?


Solution

  • 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.