如何阻止未登录用户通过BottomNavBar访问特定页面
核心逻辑
在底部导航栏点击事件中加入登录状态判断:
- 首页(index=0)直接允许访问,无需登录验证
- 其他页面需先检查登录状态,未登录则跳转登录页,已登录正常切换页面
具体修改步骤
1. 添加登录状态标记
在_HomePageState类中新增变量,用于记录用户是否已登录:
bool _isLoggedIn = false;
2. 初始化时同步登录状态
修改初始化方法,先判断用户是否登录,再获取用户类型(避免空指针错误):
@override void initState() { super.initState(); checkLoginStatus(); } Future checkLoginStatus() async { User? user = FirebaseAuth.instance.currentUser; // 先更新登录状态 setState(() { _isLoggedIn = user != null; }); // 已登录的情况下再获取用户类型 if (user != null) { String? userType = await dbhandler.getUserData(user.uid); setState(() { isAdmin = userType == 'admin'; }); } }
3. 修改底部导航点击事件
重写_navigateBottomBar方法,加入登录校验逻辑:
void _navigateBottomBar(int index) { // 首页直接切换,无需登录 if (index == 0) { setState(() { _selectedIndex = index; }); return; } // 非首页判断登录状态 if (!_isLoggedIn) { // 跳转登录页,这里假设你的登录页是AuthGate Navigator.push( context, MaterialPageRoute(builder: (context) => const AuthGate()), ).then((_) { // 登录成功返回后,刷新登录状态 checkLoginStatus(); // 可选:登录后自动跳转到用户之前点击的目标页面 // setState(() { // _selectedIndex = index; // }); }); } else { // 已登录,正常切换页面 setState(() { _selectedIndex = index; }); } }
4. 给AuthGate添加返回按钮
在你的AuthGate页面中添加关闭按钮,点击可返回首页:
// 示例:在AuthGate的AppBar中添加返回按钮 AppBar( leading: IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context), ), title: const Text('登录'), )
5. 登录成功后的状态同步
用户在AuthGate完成登录后,FirebaseAuth会自动同步用户状态,返回HomePage时checkLoginStatus会更新_isLoggedIn变量,确保后续导航正常。
完整修改后的代码
class HomePage extends StatefulWidget { const HomePage({super.key}); @override State<HomePage> createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { int _selectedIndex = 0; bool _isLoggedIn = false; // 登录状态标记 bool isAdmin = false; final dbhandler = DBHandler(); void _navigateBottomBar(int index) { if (index == 0) { setState(() { _selectedIndex = index; }); return; } if (!_isLoggedIn) { Navigator.push( context, MaterialPageRoute(builder: (context) => const AuthGate()), ).then((_) { checkLoginStatus(); // 可选:登录后自动跳转到目标页面 // setState(() { // _selectedIndex = index; // }); }); } else { setState(() { _selectedIndex = index; }); } } final List<Widget> _pages = const [ Home(), Book(), Appointments(), ProfilePages(), ]; @override void initState() { super.initState(); checkLoginStatus(); } Future checkLoginStatus() async { User? user = FirebaseAuth.instance.currentUser; setState(() { _isLoggedIn = user != null; }); if (user != null) { String? userType = await dbhandler.getUserData(user.uid); setState(() { isAdmin = userType == 'admin'; }); } } @override Widget build(BuildContext context) => isAdmin ? const AdminPage() : Scaffold( backgroundColor: Colors.black, body: _pages[_selectedIndex], bottomNavigationBar: BottomNavigationBar( selectedFontSize: 12, unselectedFontSize: 10, backgroundColor: Colors.grey[100], currentIndex: _selectedIndex, onTap: _navigateBottomBar, type: BottomNavigationBarType.fixed, items: const [ BottomNavigationBarItem( label: 'Home', icon: Icon(Icons.home), ), BottomNavigationBarItem( label: 'Book', icon: Icon(Icons.app_registration), ), BottomNavigationBarItem( label: 'Appointments', icon: Icon(Icons.assignment_outlined), ), BottomNavigationBarItem( label: 'Settings', icon: Icon(Icons.settings), ), ], ), ); }
内容的提问来源于stack exchange,提问作者Milan Labus
相关产品推荐
相关产品推荐

