当前位置:   article > 正文

Flutter TabController 多次调用,导致切换异常问题

flutter tabcontroller

Flutter  中,TabController 是连接 TabBar 与 TabBarView 的纽带,处理选中状态时必不可少的内容。

但是当我们在监听 TabController 时,会发现又多次调用

  1. @override
  2. void initState() {
  3. super.initState();
  4. _tabController = TabController(vsync: this, length: myTabs.length);
  5. _tabController.addListener(() {
  6. debugPrint('initState currentIndex=${_tabController.index}');
  7. });
  8. }

对应的多次调用日志如下。

  1. [ +153 ms] I/flutter (13788): initState currentIndex=2
  2. [ +344 ms] I/flutter (13788): initState currentIndex=2
  3. [+9932 ms] I/ViewRootImpl@9e6d4e6[MainActivity](13788): ViewPostIme pointer 0
  4. [ +94 ms] I/ViewRootImpl@9e6d4e6[MainActivity](13788): ViewPostIme pointer 1
  5. [ +5 ms] I/flutter (13788): initState currentIndex=0
  6. [ +320 ms] I/flutter (13788): initState currentIndex=0

但是为什么会调用两次呢,是bug(重复调用)还是 feature(其他用途),我们需要增加一个额外的信息打印。

  1. @override
  2. void initState() {
  3. super.initState();
  4. _tabController = TabController(vsync: this, length: myTabs.length);
  5. _tabController.addListener(() {
  6. final currentIndex = _tabController.index;
  7. final isIndexChanging = _tabController.indexIsChanging;
  8. debugPrint('initState currentIndex=$currentIndex;isIndexChanging=$isIndexChanging');
  9. });
  10. }

添加额外信息后的日志

  1. [ +34 ms] I/flutter (13788): initState currentIndex=2;isIndexChanging=true
  2. [ +308 ms] I/flutter (13788): initState currentIndex=2;isIndexChanging=false

Aha, 原来是这样。但是 isIndexChanging 是什么意思呢

  1. /// True while we're animating from [previousIndex] to [index] as a
  2. /// consequence of calling [animateTo].
  3. ///
  4. /// This value is true during the [animateTo] animation that's triggered when
  5. /// the user taps a [TabBar] tab. It is false when [offset] is changing as a
  6. /// consequence of the user dragging (and "flinging") the [TabBarView].
  7. bool get indexIsChanging => _indexIsChangingCount != 0;

注释比较简单,大概的意思是

  • 当调用 animateTo 从 previousIndex 到 index 时 会返回true

  • animateTo 触发是通过  用户点击 TabBar 的 tab 触发

  • 当TabBarView 处于 用户拖拽或者 flinging 后,返回false

然后我又再次做了一些验证,下面是一些现象

  • 点击 TabBar 的 Tab 会触发两条回调,indexIsChanging 第一次是true,第二次为false

  • 手势滑动TabBarView  只有一次回调,indexIsChanging 为 false

  • 手势滑动TabBarView 不松开,不易产生回调,松开后才会产生。

那我该怎么用

综合上面的现象和文档描述,我们在处理切换时,可以判断 indexIsChanging 为 false 后,使用index值。

  1. @override
  2. void initState() {
  3. super.initState();
  4. _tabController = TabController(vsync: this, length: myTabs.length);
  5. _tabController.addListener(() {
  6. if (!_tabController.indexIsChanging) {
  7. //do your work
  8. }
  9. });
  10. }

在具体项目中,如果不进行indexIsChanging判断,可能回调至页面切换错乱,比如从第一个tab切到第三个tab,实际是切到了第二个tab。

按照上面的处理,进行indexIsChanging判断即可解决问题。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/431993
推荐阅读
相关标签
  

闽ICP备14008679号