在Flutter中粗卜,TabController
的addListener
方法會(huì)在TabController
狀態(tài)發(fā)生變化時(shí)觸發(fā)監(jiān)聽(tīng)器庶橱。然而轻专,當(dāng)用戶點(diǎn)擊一個(gè)已經(jīng)選中的標(biāo)簽頁(yè)(tab)時(shí)蚓峦,TabController
的index
屬性不會(huì)改變徽级,但是indexIsChanging
屬性會(huì)先變?yōu)?code>true然后又變回false
气破,這通常會(huì)導(dǎo)致addListener
中的回調(diào)被觸發(fā)兩次。
具體來(lái)說(shuō)餐抢,當(dāng)你點(diǎn)擊一個(gè)標(biāo)簽頁(yè)時(shí):
- Flutter首先設(shè)置
indexIsChanging
為true
以表明正在更改索引现使。 - 如果你點(diǎn)擊的是當(dāng)前已激活的標(biāo)簽頁(yè),
index
實(shí)際上沒(méi)有變化旷痕。 - 在
indexIsChanging
從true
變回false
時(shí)碳锈,addListener
的回調(diào)被觸發(fā)一次。 - 因?yàn)?code>index沒(méi)有實(shí)際變化苦蒿,但
indexIsChanging
經(jīng)歷了完整的true
到false
的變化殴胧,所以回調(diào)可能再次被觸發(fā),導(dǎo)致看起來(lái)像是index
變化被檢測(cè)了兩次佩迟。
為了避免這種情況团滥,你可以在addListener
的回調(diào)中檢查indexIsChanging
的狀態(tài),確保只在index
真正改變時(shí)才調(diào)用你的方法报强。修改后的代碼如下:
controller!.addListener(() {
if (!controller!.indexIsChanging) return;
if (controller!.index == 0) {
_provider.getBeansBonus();
} else if (controller!.index == 1) {
_provider.getScoreBonus("scorePot");
}
});
或者灸姊,更簡(jiǎn)單的方法是使用controller.animateTo
來(lái)切換標(biāo)簽頁(yè),而不是直接設(shè)置index
秉溉。animateTo
方法不會(huì)觸發(fā)額外的indexIsChanging
事件力惯,因此可以避免重復(fù)調(diào)用問(wèn)題碗誉。
但是,在實(shí)際應(yīng)用中父晶,如果你的API調(diào)用是冪等的(即多次調(diào)用相同參數(shù)的請(qǐng)求產(chǎn)生的效果與調(diào)用一次相同)哮缺,那么重復(fù)調(diào)用可能不是問(wèn)題。然而甲喝,如果API有副作用(如計(jì)數(shù)器增加或數(shù)據(jù)庫(kù)更新)尝苇,則需要確保避免不必要的重復(fù)調(diào)用。