flutterflutter-layoutmaterial-designthemescolor-scheme

Flutter ThemeData: colorScheme is prioritized for button text color instead of ElevatedButtonTheme textStyle


I am currently trying to define the ThemeData for my material app and I need the ButtonStyle in ElevatedButtonThemeData to control the appearance of all the buttons in my app. So far, everything works fine but for some reason the "color" field for my buttons' TextStyle is overridden by the "onPrimary" field in my theme's ColorScheme.

Everything else works fine in textStyle, for instance, if I change the fontSize in TextStyle, then the font size is updated across my entire app but changing the color does nothing. Also, the backgroundColor works fine for the ButtonStyle.

I know that I can just wrap all of my buttons in a theme widget, but I want to avoid that if possible.

This is the color that ends up being used

      theme: ThemeData(
        brightness: Brightness.light,
        colorScheme: const ColorScheme(
          brightness: Brightness.light,
          primary: Colors.white,

          ///////////////////////////////////////
          onPrimary: Colors.red,
          //this is the color that is used
       ),

this is the color I want to use

elevatedButtonTheme: ElevatedButtonThemeData(
          //this themedata controls themedata for elevated buttons
          style: ButtonStyle(
            //for some reason the MarterialStateProperty must be called to explicitly define types for buttons
            //ie: "MaterialStateProperty.all<Color>(const Color(0xFF50D2C2))" just allows "const Color(0xFF50D2C2)" to be used
            backgroundColor: MaterialStateProperty.all<Color>(const Color(0xFF50D2C2)), //this is the color of the button background
            textStyle: MaterialStateProperty.all<TextStyle>(const TextStyle(
              //this determines the text style of the text displayed on buttons
              fontSize: 14,
              fontFamily: 'Lato',

              ///////////////////////////////////
              color: Colors.white,
              //this is the color I want

            ),),
            enableFeedback: true,
          ),
        ),

and this is my recreation of the issue using flutter's default demo to recreate it.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        brightness: Brightness.light,
        colorScheme: const ColorScheme(
          brightness: Brightness.light,
          primary: Colors.white,

          ///////////////////////////////////////
          onPrimary: Colors.red,
          //this is the color that is used

          secondary: Color(0xFFe8f3f2),
          onSecondary: Color(0xFF7a7a7a),
          error: Color(0xFFff3366),
          onError: Colors.white,
          background: Colors.white,
          onBackground: Color(0xFF7a7a7a),
          surface: Color(0xFF50D2C2),
          onSurface: Colors.white,
        ),

        elevatedButtonTheme: ElevatedButtonThemeData(
          //this themedata controls themedata for elevated buttons
          style: ButtonStyle(
            //for some reason the MarterialStateProperty must be called to explicitly define types for buttons
            //ie: "MaterialStateProperty.all<Color>(const Color(0xFF50D2C2))" just allows "const Color(0xFF50D2C2)" to be used
            backgroundColor: MaterialStateProperty.all<Color>(const Color(0xFF50D2C2)), //this is the color of the button background
            textStyle: MaterialStateProperty.all<TextStyle>(const TextStyle(
              //this determines the text style of the text displayed on buttons
              fontSize: 14,
              fontFamily: 'Lato',

              ///////////////////////////////////
              color: Colors.white,
              //this is the color I want

            ),),
            enableFeedback: true,
          ),
        ),
      ),
      home: const MyHomePage(title: 'Flutter Button Theme'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: const Text("This is a button"),
              onPressed: () { },
            )
          ],
        ),
      ),
    );
  }
}

Solution

  • Welp, I just spent 6 hours trying to find the answer to this issue and then figured it out 5 minutes after posting the question.

    Button text color is controlled by the foregroundColor parameter, not textStyle.

    elevatedButtonTheme: ElevatedButtonThemeData(
          //style: ElevatedButton.styleFrom(onPrimary: Colors.white)
          //this themedata controls the 
          style: ButtonStyle(
            //for some reason the MarterialStateProperty must be called to explicitly define types for buttons
            //ie: "MaterialStateProperty.all<Color>(const Color(0xFF50D2C2))" just allows "const Color(0xFF50D2C2)" to be used
            backgroundColor: MaterialStateProperty.all<Color>(const Color(0xFF50D2C2)),
            foregroundColor: MaterialStateProperty.all<Color>(Colors.white), //actual text color
            textStyle: MaterialStateProperty.all<TextStyle>(const TextStyle(
              //this determines the text style of the text displayed on buttons
              fontSize: 14,
              fontFamily: 'Lato',
              color: Colors.red, //color not used
            ),),
            enableFeedback: true,
            //minimumSize: ,
          ),
        ),