I'm new to Flutter and am working through the intro course on Udacity. In one of the tasks, I was trying to follow the code and I can't make much sense of it. Here's the code from the solution of the project (I've cut and paste the parts that matter, and also legal disclaimer I do not own any of this code, it's from the sample Flutter Udacity project):
Widget build(BuildContext context) {
final input = Padding(
padding: _padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(...),
_createDropdown(_fromValue.name, _updateFromConversion),
],
),
);
}
void _updateFromConversion(dynamic unitName) {
setState(() {
_fromValue = _getUnit(unitName);
});
if (_inputValue != null) {
_updateConversion();
}
}
Widget _createDropdown(String currentValue, ValueChanged<dynamic> onChanged) {
return Container(
margin: EdgeInsets.only(top: 16.0),
decoration: BoxDecoration(...),
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Theme(...),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton(
value: currentValue,
items: _unitMenuItems,
onChanged: onChanged,
style: Theme.of(context).textTheme.title,
),
),
),
),
);
}
Here's where I'm stuck. _updateFromConversion requires an input parameter unitName. But when they call it, in _createDropdown, they don't pass any. So how does _updateFromConversion know what unitName is? Also, is _updateFromConversion executed before _createDropdown, or is it executed when the "onChanged" property of DropdownButton is set?
Second question: they're passing that function with return type void into _createDropdown, which is expecting ValueChanged. Shouldn't this throw an error?
If someone can explain the flow of this code and what I am missing I would greatly appreciate it. Thank you!
You seem to be misunderstanding the assignment of a variable to a function for a function call.
Let me try to show it with example code.
When you run this code, you will see this printed:
This shows that the
_updateFromConversionfunction is not called when you create theSomeClassinstance inSomeClass()..myFunction = _updateFromConversion;. This is only an assignment (it assigns to the fieldmyFunctionthe value_updateFromConversion... yes, in Dart a function itself can be a value)!You should know that because there's no
()after the function name, and function invocation in Dart always must contain the list of arguments between()even if it's empty.So, here's where the function is invoked:
See? There's a list of arguments containing a single value,
"foo". That's why the function then printsUnit name: foo, because the argumentunitNametakes the value"foo".TL;DR
This is a function invocation:
This is NOT: