切换导航
{{systemName}}
{{ info.Title }}
{{info.Title}}
{{ menu.Title }}
{{menu.Title}}
登录
|
退出
搜索
flutter tabbar点击切换加载两次如何解决
作者:ych
#### 问题描述 flutter tabbar点击切换加载两次 #### 解决方案1 点击切换tab的时候会回调两次,左右滑动切换tab正常调用一次 原因:点击切换tab的时候执行了一个动画效果,滑动切换的时候是没有的,在这个过程中触发了一次Listener 解决: ``` _tabController.addListener(() { if (_tabController.index == _tabController.animation.value) { currentTopTabIndex = _tabController.index; } }); ``` 详细解释: https://www.freesion.com/article/23711034166/. #### 解决方案2 Flutter TabController 多次调用,导致切换异常问题 Flutter 中,TabController 是连接 TabBar 与 TabBarView 的纽带,处理选中状态时必不可少的内容。 但是当我们在监听 TabController 时,会发现又多次调用 ``` @override void initState() { super.initState(); _tabController = TabController(vsync: this, length: myTabs.length); _tabController.addListener(() { debugPrint('initState currentIndex=${_tabController.index}'); }); } ``` 对应的多次调用日志如下。 ``` [ +153 ms] I/flutter (13788): initState currentIndex=2 [ +344 ms] I/flutter (13788): initState currentIndex=2 [+9932 ms] I/ViewRootImpl@9e6d4e6[MainActivity](13788): ViewPostIme pointer 0 [ +94 ms] I/ViewRootImpl@9e6d4e6[MainActivity](13788): ViewPostIme pointer 1 [ +5 ms] I/flutter (13788): initState currentIndex=0 [ +320 ms] I/flutter (13788): initState currentIndex=0 ``` 但是为什么会调用两次呢,是bug(重复调用)还是 feature(其他用途),我们需要增加一个额外的信息打印。 ``` @override void initState() { super.initState(); _tabController = TabController(vsync: this, length: myTabs.length); _tabController.addListener(() { final currentIndex = _tabController.index; final isIndexChanging = _tabController.indexIsChanging; debugPrint('initState currentIndex=$currentIndex;isIndexChanging=$isIndexChanging'); }); } ``` 添加额外信息后的日志 ``` [ +34 ms] I/flutter (13788): initState currentIndex=2;isIndexChanging=true [ +308 ms] I/flutter (13788): initState currentIndex=2;isIndexChanging=false Aha, 原来是这样。但是 isIndexChanging 是什么意思呢 /// True while we're animating from [previousIndex] to [index] as a /// consequence of calling [animateTo]. /// /// This value is true during the [animateTo] animation that's triggered when /// the user taps a [TabBar] tab. It is false when [offset] is changing as a /// consequence of the user dragging (and "flinging") the [TabBarView]. 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值。 ``` @override void initState() { super.initState(); _tabController = TabController(vsync: this, length: myTabs.length); _tabController.addListener(() { if (!_tabController.indexIsChanging) { //do your work } }); } ``` 在具体项目中,如果不进行indexIsChanging判断,可能回调至页面切换错乱,比如从第一个tab切到第三个tab,实际是切到了第二个tab。 按照上面的处理,进行indexIsChanging判断即可解决问题。
相关推荐
flutter报错Error: Member not found
flutter 错误:uses-sdk:minSdkVersion 16 不能小于库中声明的版本20
flutter报错 Error: Connection refused
评论区
先去登录
版权所有:机遇屋在线 Copyright © 2021-2025 jiyuwu Co., Ltd.
鲁ICP备16042261号-1