Flutter中PageController绑定多滚动视图报错问题求助
问题根源
全局AppTabHandlerProvider中的PageController是持久化的,当用户退出登录后,原有的PageView虽被路由移除,但框架未完全解除控制器与旧视图的绑定;重新登录进入新的PageView时,同一个控制器被绑定到新视图,触发ScrollController attached to multiple scroll views断言错误。
解决方案
1. 修正Provider的控制器管理逻辑
修改AppTabHandlerProvider,添加控制器重置方法,在退出登录时销毁旧控制器并创建新实例:
/// # App Tab Handler Provider /// /// Provides state of BottomNavigationBar. class AppTabHandlerProvider with ChangeNotifier { /// Bottom tab bar index int bottomNavigationIndex = 0; /// Tab bar controller. A glue between [PageView] and [BottomNavigationBar]. late PageController pageController; AppTabHandlerProvider() { _initController(); } void _initController() { pageController = PageController(initialPage: bottomNavigationIndex); } /// 重置控制器(用于退出登录场景) void resetController() { // 销毁旧控制器 pageController.dispose(); // 重置索引 bottomNavigationIndex = 0; // 初始化新控制器 _initController(); notifyListeners(); } /// Sets new tab index to change page view set setNewPageControllerIndex(int index) { if (bottomNavigationIndex != index) { bottomNavigationIndex = index; pageController.jumpToPage(index); notifyListeners(); } } /// # System Pop Navigation /// /// Connects bottom Navigation buttons to system navigation pop button. Fixes /// behavior of SystemPopNavigationButton to BottomNavigationButtons. Future<bool> systemPopNavigation() async { if (bottomNavigationIndex >= 1 && bottomNavigationIndex <= 4) { setNewPageControllerIndex = 0; return false; // 拦截系统返回,留在当前页面 } else { // 退出应用 await SystemChannels.platform.invokeMethod("SystemNavigator.pop"); return true; } } }
2. 在退出登录时调用控制器重置
在设置页面的退出登录逻辑中,先重置控制器再导航到登录页:
// 退出登录按钮点击事件 onPressed: () async { // 执行登出操作(如清除本地token、用户信息等) await yourAuthService.logout(); // 获取全局Provider并重置控制器 Provider.of<AppTabHandlerProvider>(context, listen: false).resetController(); // 导航到登录页(使用pushReplacement避免返回栈残留) Navigator.pushReplacementNamed(context, "/"); }
3. 修正WillPopScope的回调类型
确保onWillPop返回Future<bool>,这是Flutter框架的要求,修改后的systemPopNavigation已适配该返回类型。
原理说明
退出登录时主动销毁旧的PageController并创建新实例,确保重新进入PageView时绑定的是全新控制器,彻底切断与旧视图的关联,避免出现一个控制器绑定多个滚动视图的情况。
内容的提问来源于stack exchange,提问作者Alireza Soltani Neshan
相关产品推荐
相关产品推荐

