Как вы можете вызвать функцию void во Flutter без передачи параметра? - PullRequest
1 голос
/ 22 марта 2020

Я новичок во Флаттере и прохожу вводный курс по Udacity. В одной из задач я пытался следовать коду и не могу понять его. Вот код из решения проекта (я вырезал и вставил важные части, а также юридический отказ от ответственности. Мне не принадлежит этот код, он взят из примера проекта Flutter Udacity):

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,
            ),
          ),
        ),
      ),
    );
}

Вот где я застрял. Для _updateFromConversion требуется входной параметр unitName. Но когда они вызывают это, в _createDropdown они не пропускают ничего. Так как же _updateFromConversion узнать, что такое unitName? Кроме того, выполняется ли _updateFromConversion перед _createDropdown или выполняется, когда установлено свойство onChanged DropdownButton?

Второй вопрос: они передают эту функцию с возвращаемым типом void в _createDropdown, который ожидает ValueChanged. Разве это не должно вызвать ошибку?

Если кто-то может объяснить поток этого кода и то, что мне не хватает, я был бы очень признателен. Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 марта 2020

Вы, кажется, неправильно понимаете присвоение переменной функции для вызова функции.

Позвольте мне попытаться показать это с примером кода.

void _updateFromConversion(dynamic unitName) {
    print("Unit name: $unitName");
}

class SomeClass {
    void Function(dynamic arg) myFunction;
}

void main() {
    final c = SomeClass()..myFunction = _updateFromConversion;
    print("Created c. Calling its function");
    c.myFunction("foo");
    print("Done");
}

Когда вы запустите это код, вы увидите следующее:

Created c. Calling its function
Unit name: foo
Done

Это показывает, что функция _updateFromConversion не вызывается при создании экземпляра SomeClass в SomeClass()..myFunction = _updateFromConversion;. Это только присвоение (оно присваивает полю myFunction значение _updateFromConversion ... да, в Dart сама функция может быть значением)!

Вы должны знать это, потому что нет () после имени функции и вызова функции в Dart всегда должен содержать список аргументов между (), даже если он пуст.

Итак, вот где вызывается функция:

c.myFunction("foo");

Видеть? Есть список аргументов, содержащих одно значение, "foo". Вот почему функция печатает Unit name: foo, потому что аргумент unitName принимает значение "foo".

TL; DR

Это вызов функции:

c.myFunction("foo");

Это НЕ:

c.myFunction;
0 голосов
/ 22 марта 2020

Яшвин,

Функция дротика может передаваться в качестве параметра другим функциям. Это обычно используется для передачи обратных вызовов, например.

В приведенном вами примере функция _updateFromConversion передается в качестве параметра onChanged другой функции _createDropdown.

В этой функции она будет назначена прослушивателю onChanged кнопки DropdownButton.

Every изменяется значение времени DropdownButton, эта функция будет вызвана и будет передано выбранное значение DropdownButton.

...