wzr1337
wzr1337

Reputation: 3767

How to access the Widget from within its own callback (onPressed) in Dart/Flutter

I have the following code:

  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 72.0, // in logical pixels
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
      decoration: new BoxDecoration(color: Colors.white),
      // Row is a horizontal, linear layout.
      child: new MaterialButton(
        child: new Text(
          _sprinkler.name,
          style: new TextStyle(color: Colors.white)
          ),
        splashColor: Colors.blueAccent,
        color: Colors.blue[800],
        onPressed: () {
          print("onTap(): tapped" + _sprinkler.name);
        },
      ),
    );
  }

onPressed(), I want to change the Buttons style - to represent sprinkler activity.

Therefore, I would need to acces the MaterialButton Widget itself.

But how to I access it from within the callback?

Thanks a lot in advance, and sorry for the n00b question, I am new to Dart and Flutter ;)

Upvotes: 8

Views: 4365

Answers (3)

wzr1337
wzr1337

Reputation: 3767

Thanks for your comments. The correct solution is actualy what you recommended and looks like so:

class SprinklerListItem extends StatefulWidget {
  // This class is the configuration for the state. It holds the
  // values (in this nothing) provided by the parent and used by the build
  // method of the State. Fields in a Widget subclass are always marked "final".
  final Sprinkler _sprinkler;
  SprinklerListItem(this._sprinkler);


  @override
  _SprinklerListItemState createState() {
    return new _SprinklerListItemState(this._sprinkler);
  }
}


class _SprinklerListItemState extends State<SprinklerListItem> {
  final Sprinkler _sprinkler;

  _SprinklerListItemState(this._sprinkler);

  Color textColor = Colors.white;
  Color bgColor = Colors.blue[800];
  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 72.0, // in logical pixels
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
      decoration: new BoxDecoration(color: Colors.white),
      // Row is a horizontal, linear layout.
      child: new MaterialButton(
        child: new Text(
          _sprinkler.name,
          style: new TextStyle(color: textColor)
          ),
        splashColor: Colors.blueAccent,
        color: bgColor,
        onPressed: () {
          this.setState(() {
            textColor = Colors.grey;
            bgColor = Colors.red;
          });
        },
      ),
    );
  }
}

Upvotes: 2

Bram  Vanbilsen
Bram Vanbilsen

Reputation: 6505

You could make some of the properties a variable. Then you can call setState() in your onPressed() to change the property variable.
This example shows how to change your text color of the button by using this method:

  Color textColor = Colors.white;
  @override
  Widget build(BuildContext context) {
    return new Container(
      height: 72.0, // in logical pixels
      padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 8.0),
      decoration: new BoxDecoration(color: Colors.white),
      // Row is a horizontal, linear layout.
      child: new MaterialButton(
        child: new Text(
          _sprinkler.name,
          style: new TextStyle(color: textColor)
          ),
        splashColor: Colors.blueAccent,
        color: Colors.blue[800],
        onPressed: () {
          this.setState(() {
            textColor = Colors.red;
          })
        },
      ),
    );
  }

Upvotes: 3

Zev
Zev

Reputation: 169

You probably want to use a StatefulWidget, something like this:

class MyWidget extends StatefulWidget {
  _MyWidgetState createState() => new _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
  Color c = Colors.blue.shade500;

  Widget build() => new MaterialButton(
    color: c,
    onPressed: () => setState(() {
      c = Colors.red.shade500;
    }),
  );
}

Upvotes: 2

Related Questions