将函数作为参数传递Flutter-无法在初始化程序中访问实例成员'_handleChange'

时间:2020-10-20 17:09:20

标签: flutter arguments flutter-web

我有一堂这样的课

class MyClass extends StatefulWidget {
  const MyClass({
    Key key,
    this.onChange,
  }) : super(key: key);

  final VoidCallback onChange;
  @override
  _MyClassState createState() => _MyClassState();
}

,并且需要从父级传递onChange。在父级中,我已如下定义它,并在其中尝试将其传递给MyClass的widget变量

class _ParentClassState extends State<ParentClass> {
  Widget myWidget = MyClass(onChange: _handleChange,);

  void _handleChange(arg) {
    setState(() {
      someStateVar = arg;
    });
  }
}

这不起作用,有两个错误

The argument type 'void Function(dynamic)' can't be assigned to the parameter type 'dynamic Function()'. 
The instance member '_handleChange' can't be accessed in an initializer.

感谢您的帮助,谢谢

还:是否有更好的体系结构来传递函数,该函数将设置父级中的状态变量?

编辑:使用下面的rstrelba答案修复了第一个错误,现在仅存在

The instance member '_handleChange' can't be accessed in an initializer.

我正在尝试这个答案https://stackoverflow.com/a/54415287/3808307并且在做

  Widget myWidget = MyClass(onChange: _ParentClassState()._handleChange,);

错误消失了,但是堆栈超出了

2 个答案:

答案 0 :(得分:1)

一些我的代码

呼叫者:

catTree = CatTree(onChangeCat: _onChangeCat);
'''
  _onChangeCat(int catId) {
    //
    debugPrint('_onChangeCat callback!');
  }

UI:

class CatTree extends StatefulWidget {
  final Function(int catId) onChangeCat;
  CatTree({this.onChangeCat});
}

状态:

class _CatTreeState extends State<CatTree> {
.....

>>>this.widget.onChangeCat(e.id);
}

答案 1 :(得分:1)

// 1. you can define the type of function you want to pass as a type like this
typedef ChangeCallback<T> = void Function(T value);

class MyClass extends StatefulWidget {
  const MyClass({
    Key key,
    this.onChange,
  }) : super(key: key);

  // 2. and use it like this
  final ChangeCallback onChange;

  @override
  _MyClassState createState() => _MyClassState();
}

第二个错误修复:

解决方案1:

class _ParentClassState extends State<ParentClass> {
  Widget myWidget = MyClass(onChange: (arg) {
    setState(() {
      someStateVar = arg;
    });
  },
);
}

解决方案2:

class _ParentClassState extends State<ParentClass> {
  Widget myWidget;

  void _handleChange(arg) {
    setState(() {
      someStateVar = arg;
    });
  }
  @override
  void initState(){
    super.initState();
    myWidget = MyClass(onChange: _handleChange);
  }
}