You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止未登录用户通过BottomNavBar访问特定页面

解决Flutter 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 09:40:39