How to solve: Flutter Opacity doesn't work on Ink Widget

Question

Asked by JackJarson on January 03, 2022 (source).

I try to make a disable style using elevated button with Opacity. But it just makes the child of button(the text) looks transparent, the color of button doesn't change. image

    Widget build(BuildContext context) {
    return Opacity(
      opacity: widget.disable? 0.4:1,
      child: Ink(
        width: widget.width,
        height: widget.height,
        decoration: BoxDecoration(
            gradient: buttonColor(widget.buttonState),
            borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)),
            boxShadow: [buttonShadow(widget.buttonState)]),
        child: ElevatedButton(
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
            shadowColor: MaterialStateProperty.all<Color>(Colors.transparent),
            overlayColor: MaterialStateProperty.all<Color>(Colors.yellow),
            padding: MaterialStateProperty.all<EdgeInsetsGeometry>(EdgeInsets.zero),
            minimumSize: MaterialStateProperty.all<Size>(Size(widget.width, widget.height)),
            splashFactory: InkSplash.splashFactory,
          ),
          onPressed: widget.disable ? null : widget.onPressed,
          child: Container(
              padding: widget.padding,
              alignment: Alignment.center,
              child: widget.child),
        ),
      ),
    );
  }

Here is the color of buttons. Is there a better way to control the opacity of button then add "withOpacity" to colors one by one?

LinearGradient buttonColor(ButtonState state) {
    switch (state) {
      case ButtonState.second:
        return LinearGradient(
            colors: [_button_secondary1, _button_secondary2], begin: Alignment(-0.91, 0.4), end: Alignment(0.91, -0.4));
      case ButtonState.sup:
        return LinearGradient(colors: [_button_support, _button_support]);
      case ButtonState.secondSup:
        return LinearGradient(colors: [_button_secondarySupport, _button_secondarySupport]);
      case ButtonState.main:
      default:
        return LinearGradient(
            colors: [_button_primary1, _button_primary2], begin: Alignment(-0.91, 0.4), end: Alignment(0.91, -0.4));
    }
  }

Answer

Question answered by JackJarson (source).

I figure out wrap the button with Container or DecoratedBox instead of Ink, and it goes well with Opacity effect.

Widget build(BuildContext context) {
    return Opacity(
      opacity: widget.onPressed == null ? 0.4 : 1,
      child: DecoratedBox(
        decoration: BoxDecoration(
            gradient: _buttonColor(widget.buttonType),
            borderRadius: BorderRadius.all(Radius.circular(widget.borderRadius)),
            border: Border.all(
                width: 1,
                color: _button_support_border,
                style: widget.buttonType == ButtonType.sup ? BorderStyle.solid : BorderStyle.none),
            boxShadow: widget.withShadow ? [_buttonShadow(widget.buttonType)]:[]),
        child: ElevatedButton(
          style: ButtonStyle(
            backgroundColor: MaterialStateProperty.all<Color>(Colors.transparent),
            shadowColor: MaterialStateProperty.all<Color>(Colors.transparent),
            overlayColor: widget.buttonType == ButtonType.sup ? MaterialStateProperty.all<Color>(Color(0x7ce8e8e8)):null,
            padding: MaterialStateProperty.all<EdgeInsetsGeometry>(widget.padding),
            minimumSize: MaterialStateProperty.all<Size>(Size(widget.width ?? 108.w, widget.height ?? 48.h)),
            tapTargetSize: MaterialTapTargetSize.shrinkWrap,
            splashFactory: InkSplash.splashFactory,
            elevation: MaterialStateProperty.all<double>(0),//avoid elevation shadow on Android
            alignment: Alignment.center,
          ),
          onPressed: widget.onPressed,
          child: widget.child,
        ),
      ),
    );
  }

Video Answers on YouTube

FLUTTER
SHARE: