在Flutter中,TabController的addListener方法会在TabController状态发生变化时触发监听器。然而,当用户点击一个已经选中的标签页(tab)时,TabController的index属性不会改变,但是indexIsChanging属性会先变为true然后又变回false,这通常会导致addListener中的回调被触发两次。
具体来说,当你点击一个标签页时:
- Flutter首先设置
indexIsChanging为true以表明正在更改索引。 - 如果你点击的是当前已激活的标签页,
index实际上没有变化。 - 在
indexIsChanging从true变回false时,addListener的回调被触发一次。 - 因为
index没有实际变化,但indexIsChanging经历了完整的true到false的变化,所以回调可能再次被触发,导致看起来像是index变化被检测了两次。
为了避免这种情况,你可以在addListener的回调中检查indexIsChanging的状态,确保只在index真正改变时才调用你的方法。修改后的代码如下:
controller!.addListener(() {
if (!controller!.indexIsChanging) return;
if (controller!.index == 0) {
_provider.getBeansBonus();
} else if (controller!.index == 1) {
_provider.getScoreBonus("scorePot");
}
});
或者,更简单的方法是使用controller.animateTo来切换标签页,而不是直接设置index。animateTo方法不会触发额外的indexIsChanging事件,因此可以避免重复调用问题。
但是,在实际应用中,如果你的API调用是幂等的(即多次调用相同参数的请求产生的效果与调用一次相同),那么重复调用可能不是问题。然而,如果API有副作用(如计数器增加或数据库更新),则需要确保避免不必要的重复调用。