在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有副作用(如计数器增加或数据库更新),则需要确保避免不必要的重复调用。