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

Flutter:如何根据授权状态切换BottomNavigationBar的页面与标题

解决BottomNavBar根据登录状态切换页面和标题的问题

1. 修正生命周期与状态变量的问题

  • didChangeDependencies 不能标记为 async(它是同步生命周期方法),建议将令牌加载逻辑移到 initState 中执行。
  • 移除 val 的 final 修饰符,因为登录状态变化时需要更新该变量。

2. 动态生成导航项与页面

不再使用固定的列表存储页面和标题,而是根据登录状态动态返回对应内容。

完整修改代码

class YourMainScreen extends StatefulWidget {
  const YourMainScreen({super.key});

  @override
  State<YourMainScreen> createState() => _YourMainScreenState();
}

class _YourMainScreenState extends State<YourMainScreen> {
  int currentIndex = 0;
  String? val; // 移除final,允许状态更新

  @override
  void initState() {
    super.initState();
    _loadToken(); // 页面初始化时加载登录令牌
  }

  void _loadToken() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    String token = pref.getString('login') ?? "";
    setState(() {
      val = token;
      Constants.USER_TOKEN = token;
    });
  }

  // 根据当前索引和登录状态返回对应页面
  Widget _getCurrentScreen() {
    switch (currentIndex) {
      case 0:
        return HomePage();
      case 1:
        return CatalogPage();
      case 2:
        return ShoppingBag();
      case 3:
        // 登录状态判断:令牌非空则显示个人资料,否则显示登录页
        return val != null && val!.isNotEmpty ? ProfilePage() : Login();
      default:
        return HomePage();
    }
  }

  // 根据当前索引和登录状态返回对应标题
  String _getCurrentTitle() {
    switch (currentIndex) {
      case 0:
        return 'Главная';
      case 1:
        return 'Каталог';
      case 2:
        return 'Корзина';
      case 3:
        return val != null && val!.isNotEmpty ? 'Профиль' : 'Войти';
      default:
        return 'Главная';
    }
  }

  // 动态生成底部导航栏项
  List<BottomNavigationBarItem> _getNavBarItems() {
    return [
      const BottomNavigationBarItem(
        icon: Icon(Icons.home),
        label: 'Главная',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.shop),
        label: 'Каталог',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.shopping_bag),
        label: 'Корзина',
      ),
      BottomNavigationBarItem(
        icon: Icon(val != null && val!.isNotEmpty ? Icons.person : Icons.login),
        label: val != null && val!.isNotEmpty ? 'Профиль' : 'Войти',
      ),
    ];
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(_getCurrentTitle()),
      ),
      body: _getCurrentScreen(),
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentIndex,
        items: _getNavBarItems(),
        onTap: (index) {
          setState(() {
            currentIndex = index;
          });
        },
      ),
    );
  }
}

关键说明

  • _loadToken 异步加载登录令牌后,通过 setState 更新状态,触发UI重绘。
  • _getCurrentScreen 和 _getCurrentTitle 方法根据登录状态动态返回内容,实现页面和标题的切换。
  • 底部导航栏的最后一项也通过状态判断动态切换图标和文字,保持UI与登录状态同步。

内容的提问来源于stack exchange,提问作者st4tic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 09:20:29