0

I'm trying to make buttons that turn grey after having been pressed. I read up on how to do this. The best way I could find is to set the material color with a ternary operator and then change the condition for that in a setState(() {}) block:

  Container vehicleButton(IconData icon_, String text_, {required Function onClickAction}){
    const double buttonSizeX = 200;
    const double buttonSizeY = 100;
    const double iconSize = 60;
    const double buttonTextSize = 15;

    const double buttonMargin = 5;
    
    Color buttonColor = const Color(0xff2196f3);
    const Color iconColor = Color(0xffffffff);
    const Color buttonTextColor = Color(0xffffffff);

    bool pressed = false;

    return Container(padding: const EdgeInsets.only(left: buttonMargin, right: buttonMargin, top: buttonMargin, bottom: buttonMargin), child: SizedBox.fromSize(
      size: Size(buttonSizeX, buttonSizeY), child: Material(color: pressed ? Color.fromARGB(255, 143, 143, 143) : buttonColor, child: InkWell(
      onTap: () {
        setState(() {
          pressed = true;
        });
        onClickAction();
      },
      child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
          Icon(icon_, color: iconColor, size: iconSize),
          Text(text_, style: TextStyle(fontSize: buttonTextSize, color: buttonTextColor)),
    ])))));
  }

However, I'm getting a warning that the code after the ? in my ternary operator is dead code. And indeed, the button does not turn grey after pressing.

I thought maybe the values of Material are final and cannot be changed, but this wouldn't explain why all the examples I could find on the internet use this method.

Anteino
  • 1,044
  • 7
  • 28
  • 1
    Your ternary expression contains dead code because at that point, the local variable `pressed` is known to always be `false`. You perhaps do not intend for `pressed` to be a variable local to the `vehicleButton` function. – jamesdlin Feb 23 '22 at 11:23
  • How would you suggest to do it? – Anteino Feb 23 '22 at 12:05
  • you have to explicitly check condition at runtime 'pressed == true?' which I suggested in answer. If you do not check, then because of compile time check, it always becomes false causing dead code. – Varun Kumar Feb 23 '22 at 16:37
  • 1
    @Anteino As I already said, you probably want `pressed` to not be a local variable. Currently the button's `onTap` callback will have no ultimate effect: it will modify a local variable that will never be read again. If `vehicleButton` is a method on an `State`, then make `pressed` a member on that `State`. – jamesdlin Feb 23 '22 at 17:11

2 Answers2

2

You have:

Container vehicleButton(...) {
  bool pressed = false;

  return Container(
      ...
      child: SizedBox.fromSize(
          ...
          child: Material(
              color: pressed ? Color.fromARGB(255, 143, 143, 143) : buttonColor,
              child: InkWell(
                  onTap: () {
                    setState(() {
                      pressed = true;
                    });
                    onClickAction();
                  },

The Dart analysis tools are correctly reporting that Color.fromARGB(...) is dead code because the conditional ternary operator checks the state of the local pressed variable, which at the time it's checked, is always false. Although the onTap handler sets pressed = true, it's setting the state of the local pressed variable, which will never be read again.

You likely intend for pressed to be a member variable of whatever State class contains the vehicleButton method.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
1

Instead of using a SizedBox I suggest you to use the buttons provided by flutter dev: https://docs.flutter.dev/release/breaking-changes/buttons

A simple try you can give is:

RaisedButton(
      child: new Text('Attention'),
      textColor: Colors.white,
      color: pressColor ? Colors.grey : Colors.blue, //Choose your personal colors
      onPressed: () => setState(() => pressColor = !pressColor), //change the button colors
    );