颤动中的回调函数问题
Callback function issue in flutter
我在有状态小部件中有两个回调函数,它们被两个不同的屏幕调用。这是我在有状态小部件(onChange 和 finalBetList)中声明它们的方式;
class AppListView extends StatefulWidget {
final ValueChanged onChange;
final List<MatchList> matchList;
final ValueChanged finalBetList;
AppListView({this.onChange, this.matchList, this.finalBetList});
这就是我在小部件 class 状态下实现它们的方式。即使我尝试传递相同的参数 onChange 工作正常但 finalBetList 收到此错误。
在 null.Receiver 上调用了方法 'call':null 尝试调用:call(1)
widget.onChange(counter);
widget.finalBetList(counter);
一切都一样,其中一个正在运行,但另一个出现错误。我错过了什么?
编辑
这是我从 HomeScreen 调用有状态小部件的代码(完美运行)
Stack(children: [
AppListView(
matchList: matchList,
//callback function brings the counter value from ListView class
onChange: (value) {
setState(() {
counter = value;
});
},
),
这是我从第二个屏幕调用有状态小部件的代码(出现错误)
body: Container(
child: AppListView(
onChange: (value) {},
finalBetList: (value) {
counter = value;
setState(() {
//counter = value;
});
},
matchList: matchList),
),
TL;DR
将空主体实现分配给 finalBetList
属性
Stack(children: [
AppListView(
matchList: matchList,
finalBetList: (value) {}, // <- NEW CODE IS HERE
//callback function brings the counter value from ListView class
onChange: (value) {
setState(() {
counter = value;
});
},
),
为什么要这样做?
在 Dart 中,函数是对象。如果对象没有赋值,则为 null
。在 HomeScreen
的代码示例中,您将一个值赋给 onChange
,因此稍后当您通过 widget.onChange(counter)
调用它时,onChange
被评估为函数对象并执行其主体.
但是,在同一示例中,您没有为 finalBetList
分配任何值,因此它保留为 null
。当您调用 widget.finalBetList(counter)
时,finalBetList
被求值,它显然不是函数对象。此时你会排除一个错误,但这还不是故事的结尾——因为不仅可以调用函数对象。任何实现 call()
方法的 class 也可以被调用。因此尝试调用 finalBetList.call()
。这是您应该得到的异常:
NoSuchMethodError: The method 'call' was called on null.
Receiver: null
显然 null
没有实现 call()
方法,因此它不存在并抛出异常。
如果您不想将空主体实现分配给 HomeScreen
内的 finalBetList
属性,您还可以选择在构造函数中分配它。
我能想到的另一个选择是使用条件成员访问调用函数:
widget.finalBetList?.call(counter);
所有函数对象都有执行函数体的call()
方法。
我在有状态小部件中有两个回调函数,它们被两个不同的屏幕调用。这是我在有状态小部件(onChange 和 finalBetList)中声明它们的方式;
class AppListView extends StatefulWidget {
final ValueChanged onChange;
final List<MatchList> matchList;
final ValueChanged finalBetList;
AppListView({this.onChange, this.matchList, this.finalBetList});
这就是我在小部件 class 状态下实现它们的方式。即使我尝试传递相同的参数 onChange 工作正常但 finalBetList 收到此错误。 在 null.Receiver 上调用了方法 'call':null 尝试调用:call(1)
widget.onChange(counter);
widget.finalBetList(counter);
一切都一样,其中一个正在运行,但另一个出现错误。我错过了什么?
编辑
这是我从 HomeScreen 调用有状态小部件的代码(完美运行)
Stack(children: [
AppListView(
matchList: matchList,
//callback function brings the counter value from ListView class
onChange: (value) {
setState(() {
counter = value;
});
},
),
这是我从第二个屏幕调用有状态小部件的代码(出现错误)
body: Container(
child: AppListView(
onChange: (value) {},
finalBetList: (value) {
counter = value;
setState(() {
//counter = value;
});
},
matchList: matchList),
),
TL;DR
将空主体实现分配给 finalBetList
属性
Stack(children: [
AppListView(
matchList: matchList,
finalBetList: (value) {}, // <- NEW CODE IS HERE
//callback function brings the counter value from ListView class
onChange: (value) {
setState(() {
counter = value;
});
},
),
为什么要这样做?
在 Dart 中,函数是对象。如果对象没有赋值,则为 null
。在 HomeScreen
的代码示例中,您将一个值赋给 onChange
,因此稍后当您通过 widget.onChange(counter)
调用它时,onChange
被评估为函数对象并执行其主体.
但是,在同一示例中,您没有为 finalBetList
分配任何值,因此它保留为 null
。当您调用 widget.finalBetList(counter)
时,finalBetList
被求值,它显然不是函数对象。此时你会排除一个错误,但这还不是故事的结尾——因为不仅可以调用函数对象。任何实现 call()
方法的 class 也可以被调用。因此尝试调用 finalBetList.call()
。这是您应该得到的异常:
NoSuchMethodError: The method 'call' was called on null.
Receiver: null
显然 null
没有实现 call()
方法,因此它不存在并抛出异常。
如果您不想将空主体实现分配给 HomeScreen
内的 finalBetList
属性,您还可以选择在构造函数中分配它。
我能想到的另一个选择是使用条件成员访问调用函数:
widget.finalBetList?.call(counter);
所有函数对象都有执行函数体的call()
方法。