`TabController`的`addListener`方法

195 阅读1分钟

在Flutter中,TabControlleraddListener方法会在TabController状态发生变化时触发监听器。然而,当用户点击一个已经选中的标签页(tab)时,TabControllerindex属性不会改变,但是indexIsChanging属性会先变为true然后又变回false,这通常会导致addListener中的回调被触发两次。

具体来说,当你点击一个标签页时:

  1. Flutter首先设置indexIsChangingtrue以表明正在更改索引。
  2. 如果你点击的是当前已激活的标签页,index实际上没有变化。
  3. indexIsChangingtrue变回false时,addListener的回调被触发一次。
  4. 因为index没有实际变化,但indexIsChanging经历了完整的truefalse的变化,所以回调可能再次被触发,导致看起来像是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来切换标签页,而不是直接设置indexanimateTo方法不会触发额外的indexIsChanging事件,因此可以避免重复调用问题。

但是,在实际应用中,如果你的API调用是幂等的(即多次调用相同参数的请求产生的效果与调用一次相同),那么重复调用可能不是问题。然而,如果API有副作用(如计数器增加或数据库更新),则需要确保避免不必要的重复调用。