Flutter项目buildAuthScreen异常导致底部导航栏无法点击切换页面且陷入死循环
问题原因与修复方案
1 核心错误原因
- initState拼写错误:生命周期函数
initState被错写为inistate,导致初始化逻辑完全未执行:pageController未初始化、谷歌登录监听未注册、静默登录逻辑未触发,是所有问题的根源。 - 底部导航点击逻辑错误:
CupertinoTabBar的onTap回调仅修改了pageindex变量值,未调用提前定义的onTap方法触发PageController的页面跳转,也没有触发setState更新UI,所以点击无响应。 - 初始值逻辑错误:
isAuth初始值被设为true,但此时用户还未完成登录校验,会直接渲染buildAuthScreen,此时currentUser为空、pageController未初始化,访问空对象会触发异常,甚至引发重复build的死循环。 - 异步逻辑上下文风险:
createUserFireStoreData中直接在初始化阶段调用Navigator.push跳转页面,此时页面可能还未完成挂载,会出现上下文异常。 - 监听器未回收:谷歌登录的
onCurrentUserChanged监听器没有在dispose时取消,多次进入页面会重复注册监听器,触发重复逻辑导致死循环。
2 具体修复方案
2.1 新增监听器订阅变量,修正初始化拼写与逻辑
在类的变量定义区新增监听器存储变量:
StreamSubscription<GoogleSignInAccount> _googleSignInListener;
修正错误的inistate为正确的生命周期函数,添加页面挂载校验:
@override void initState() { super.initState(); pageController = PageController(); // 保存监听器订阅,后续销毁时回收 _googleSignInListener = googlesignin.onCurrentUserChanged.listen((account) { HandleSignIn(account); }, onError: (error) { print('Error sign in :$error'); }); // 静默登录逻辑放在挂载完成回调中,避免上下文异常 WidgetsBinding.instance.addPostFrameCallback((_) async { try { final account = await googlesignin.signInSilently(suppressErrors: false); HandleSignIn(account); } catch(e) { print('Error sign in:$e'); } }); }
2.2 修正dispose方法,回收资源
@override void dispose() { // 取消谷歌登录监听器,避免重复触发 _googleSignInListener?.cancel(); pageController.dispose(); super.dispose(); }
2.3 修正底部导航点击逻辑
bottomNavigationBar: CupertinoTabBar( currentIndex: pageindex, // 直接调用提前定义的onTap方法触发页面跳转 onTap: onTap, activeColor: Theme.of(context).primaryColor, items: <BottomNavigationBarItem>[ // 原有item逻辑保持不变 ], ),
2.4 修正isAuth初始值
// 初始默认未登录,等校验完成再修改状态 bool isAuth = false;
2.5 补充创建账户空值校验
final username = await Navigator.push( context, MaterialPageRoute(builder: (context) => CreateAccount()) ); // 新增空判断,避免用户直接返回页面导致username为空 if(username == null || username.toString().trim().isEmpty) { await googlesignin.signOut(); return; }
3 修复后逻辑说明
- 页面启动后默认显示未登录页面,不会提前渲染需要登录状态的主页面,避免空对象异常
- 初始化逻辑正常执行,谷歌登录状态监听正常注册,静默登录在页面挂载完成后执行,不会出现上下文错误
- 点击底部导航时会直接触发PageView跳转,onPageChanged回调会自动更新选中索引,导航状态同步更新
- 所有异步逻辑都加了异常捕获和空校验,不会出现空对象异常
- 页面销毁时会回收所有监听器和控制器,不会出现内存泄漏和重复触发的死循环
内容的提问来源于stack exchange,提问作者Abderrezak Douba
相关产品推荐
相关产品推荐

