skip to Main Content

I have following code for different variants of buttons:

import 'package:flutter/material.dart';

import '../common/texts.dart';
import '../common/colors.dart';

enum ButtonVariant { primary, secondary, text }

enum ButtonState { enabled, disabled, loading }

class CustomButton extends StatelessWidget {
  final String text;
  final ButtonVariant variant;
  final ButtonState state;
  final VoidCallback? onPressed;

  const CustomButton({
    super.key,
    required this.text,
    this.variant = ButtonVariant.primary,
    this.state = ButtonState.enabled,
    this.onPressed,
  });

  @override
  Widget build(BuildContext context) {
    Color backgroundColor;
    Color textColor;

    switch (variant) {
      case ButtonVariant.primary:
        backgroundColor = green500;
        textColor = black;
        break;
      case ButtonVariant.secondary:
        backgroundColor = Colors.blue;
        textColor = Colors.white;
        break;
      case ButtonVariant.text:
        backgroundColor = Colors.transparent;
        textColor = Colors.blue;
        break;
    }

    if (state == ButtonState.disabled) {
      backgroundColor = backgroundColor.withOpacity(0.5);
      textColor = textColor.withOpacity(0.5);
    }

    return ElevatedButton(
      style: ElevatedButton.styleFrom(
        backgroundColor: backgroundColor,
        foregroundColor: textColor,
        padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0),
        shape: RoundedRectangleBorder(
          borderRadius: BorderRadius.circular(22),
        ),
      ),
      onPressed: state == ButtonState.disabled ? null : onPressed,
      child: state == ButtonState.loading
          ? CircularProgressIndicator(
              valueColor: AlwaysStoppedAnimation<Color>(textColor),
            )
          : Text(text, style: caption2Black),
    );
  }
}

The normal behavior of ElevatedButton’s onPressed is, that if it is null, the button is disabled.

In my case, the button is not even displayed anymore. Once I change the onPressed: state == ButtonState.disabled ? null : onPressed, to onPressed: state == ButtonState.disabled ? () {} : onPressed,, the button appears (see GIF 1). Once tapped, the typical "fading" animation is seen on the button (see GIF 2).

Did anyone else experienced this issue or something similar? I did try a lot but nothing really helped.

I am running on Flutter (Channel stable, 3.13.3, on macOS 14.5 23F79 darwin-x64, locale en-DE)

This is the behavior when changing it from () {} to null

This is the clicking animation mentioned

2

Answers


  1. I couldn’t reproduce it at first but that was because I didn’t have a black background. With white background it works fine. So I believe it’s actually because a ElevatedButton‘s default disabled background and text is actually black with a certain opacity. While it’s disabled it doesn’t look at backgroundColor and foregroundColor. Adding these lines to the ElevatedButton.styleFrom should give you the desired effect:

        disabledBackgroundColor: backgroundColor,
        disabledForegroundColor: textColor,
    
    Login or Signup to reply.
  2. Give backgroundColor:

    WidgetStateProperty.all(your_color);
    

    in the

    ButtonStyle()

    widget and done.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search