Change The Text Color Of An ElevatedButton In Flutter With ButtonStyle

- 1 answer

I want a button that:

  • Changes its background color based on whether it's in the pressed, disabled or normal state
  • Changes its text color depending on whether it's in the disabled or normal state

I'm trying to achieve this with the ButtonStyle class.

  child: Text("Example"),
  onPressed: onPressed, // onPressed is a function
  style: ButtonStyle(
    backgroundColor: MaterialStateProperty.resolveWith((states) {
      if (states.contains(MaterialState.disabled)) { return KPColors.offWhite; }
      if (states.contains(MaterialState.pressed)) { return KPColors.primaryLight; }
      return KPColors.primaryExtraLight;
    textStyle: MaterialStateProperty.resolveWith((states) {
      Color textColor = states.contains(MaterialState.disabled) ? KPColors.gray : KPColors.primary;
      return TextStyle(fontSize: 18, color: textColor);
    overlayColor: MaterialStateProperty.all(KPColors.clear), // prevents the shimmer effect when pressing the button
    shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(16))), // Rounds the corners
    elevation: MaterialStateProperty.all(0), // Prevents shadow around button

The code succeeds in changing the background color of the button, but not the text color, which appears white instead of my custom color. I think this is because ElevatedButton's child is a Text widget, which has a default text color which is overriding mine.

How can I solve this? I already know that I can change the text color of the button by using ElevatedButton.styleFrom(...) and setting the onPrimary property, instead of ButtonStyle, but this would make it much more difficult to have different colors depending on the pressed and disabled states of the button.



you need to set the foregroundColor in the ButtonStyle

For example:

foregroundColor: MaterialStateProperty.resolveWith((states) {
      if (states.contains(MaterialState.disabled)) { return Colors.grey; }
      if (states.contains(MaterialState.pressed)) { return; }