10

I've been following some of the beginner flutter tutorials on their website and was doing this tutorial for basic interactivity, specifically the part where a parent widget is used to manage the state of a child widget. There is a ParentWidget and _ParentWidgetState class the code for which is as follows:

class ParentWidget extends StatefulWidget {
   @override
   _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  bool _active = false;

  void _handleTapboxChanged(bool newValue) {
    setState(() {
       _active = newValue;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: TapboxB(
        active: _active,
        onChanged: _handleTapboxChanged,
      ),
    );
  }
}

TapboxB is a class which is a child of ParentWidget, the code for which is as follows:

class TapboxB extends StatelessWidget {
  TapboxB({this.active: false, @required this.onChanged});

  final bool active;
  final ValueChanged<bool> onChanged;

  void _handleTap() {
    onChanged(!active);
  }

  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: _handleTap,
      child: Container(
        child: Column(
          //aligns column in the centre vertically
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              //sets text depending on _active boolean
              active ? 'Active' : 'Inactive',
              style: TextStyle(fontSize: 20.0, color: Colors.white),
            ),
            Text(
              'Tapbox B',
              style: TextStyle(fontSize: 14.0, color: Colors.white),
            ),
          ],
        ),
        width: 100.0,
        height: 100.0,
        decoration: BoxDecoration(
          //sets colour depending on _active boolean
          color: active ? Colors.lightGreen[700] : Colors.grey[600],
        ),
      ),
    );
  }
}

The _handleTap method is called when the widget is clicked, which calls the onChanged callback, which toggles the active variable. In the definition for onChanged the type is ValueChanged<bool> which is documented as a "signature for callbacks that report that an underlying value has changed." If I change this however to ValueSetter<bool> the app works in the exact same way and nothing seems to change. So my question is what is the difference between the two of these? Is one better in this particular scenario?

2
  • Why would you change it, instead of using the documented signature? If you have no known reason to do something, don't do it, I would say. Commented Jul 8, 2020 at 16:38
  • 4
    @underscore_d granted, but this isn't exactly a project in itself, just me getting used to flutter, and so was curious
    – Tom Ryan
    Commented Jul 8, 2020 at 16:43

1 Answer 1

15

I searched the documentation, using flutter ValueChanged ValueSetter, and found this:

void ValueSetter (T Value)

Signature for callbacks that report that a value has been set.

This is the same signature as ValueChanged, but is used when the callback is called even if the underlying value has not changed. For example, service extensions use this callback because they call the callback whenever the extension is called with a value, regardless of whether the given value is new or not.

typedef ValueSetter<T> = void Function(T value);

So they're just typedefs to the same underlying type, but one has a different semantic meaning, presumably used as self-documenting code despite the same underlying signature.

If you don't need the latter meaning of ValueSetter, then use ValueChanged, as the API thus said.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.