【问题标题】:How can you call a void function in Flutter without passing a parameter?如何在 Flutter 中调用 void 函数而不传递参数?
【发布时间】:2020-07-03 05:28:13
【问题描述】:

我是 Flutter 的新手,正在学习 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 之前执行,还是在设置 DropdownButton 的“onChanged”属性时执行?

第二个问题:他们将返回类型为 void 的函数传递给 _createDropdown,它期待 ValueChanged。这不应该抛出错误吗?

如果有人可以解释此代码的流程以及我所缺少的内容,我将不胜感激。 谢谢!

【问题讨论】:

    标签: flutter dart valuechangelistener


    【解决方案1】:

    亚什温,

    在 dart 函数中可以作为参数传递给其他函数。例如,这通常用于传递回调。

    在您提供的示例中,函数 _updateFromConversion 作为参数 onChanged 传递给另一个函数 _createDropdown。

    在该函数中,它将被分配给 DropdownButton 按钮的 onChanged 监听器。

    每次DropdownButton的值改变时,都会调用这个函数,并传递DropdownButton的选定值。

    【讨论】:

      【解决方案2】:

      您似乎误解了将变量分配给函数以进行函数调用。

      让我尝试用示例代码来展示它。

      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
      

      这说明在SomeClass()..myFunction = _updateFromConversion;中创建SomeClass实例时没有调用_updateFromConversion函数。这只是一个赋值(它为字段myFunction 赋值_updateFromConversion...是的,在Dart 中,函数本身可以是一个值)!

      你应该知道,因为函数名后面没有(),并且Dart中的函数调用总是必须包含()之间的参数列表,即使它是空的。

      所以,这里是调用函​​数的地方:

      c.myFunction("foo");
      

      看到了吗?有一个包含单个值的参数列表,"foo"。这就是为什么该函数会打印 Unit name: foo,因为参数 unitName 采用值 "foo"

      TL;DR

      这是一个函数调用:

      c.myFunction("foo");
      

      这不是:

      c.myFunction;
      

      【讨论】:

      • 这很有意义。那么还有几个后续问题:1)在我发布的代码中,他们将函数分配给 ValueChanged 类型。那么你可以将函数分配给任何类型,而不仅仅是函数类型吗? 2) _updateFromConversion 何时被调用?何时分配 onChanged 属性?因为即使在那里他们也没有传递参数。
      • ValueChanged 也是一个函数。但它是一个typedef(在这个“简单”示例中可能会引起您的注意!),它就像一个别名,因此您可以将函数类型命名为更容易记住的名称:api.flutter.dev/flutter/foundation/ValueChanged.html
      • 2) 您发布的代码未显示 _updateFromConversion 被调用...但鉴于您将其提供给 DropdownButton 小部件的字段 onChange,它必须由小部件调用每当 Widget 更改时(通过用户操作或以编程方式)。
      猜你喜欢
      • 1970-01-01
      • 2011-10-13
      • 2021-11-19
      • 2020-06-20
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 2022-01-12
      • 2012-03-03
      相关资源
      最近更新 更多