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

Flutter Curved Navigation Bar动画不同步及断言错误求助

问题描述

点击Curved Navigation Bar图标时页面可正常切换,但导航栏动画未同步更新。例如点击confirmation_num图标跳转至TicketScreen后,导航栏仍停留在首页选项;尝试更换其他导航栏组件时持续出现断言错误,期望导航栏动画与页面切换保持同步。

问题原因分析
  • 页面跳转导致状态丢失:使用Navigator.push跳转新页面时,原页面的导航栏组件被压入栈中,新页面的导航栏(若存在)是独立实例,无法共享原有currentIndex状态,导致视觉上导航栏未同步。
  • 状态管理冲突:同时维护本地currentIndex和NavigationBarController状态,两者未双向同步,且跳转后未同步新页面导航栏的选中状态。
  • 错误的页面切换逻辑:底部导航栏对应的页面不应通过push/pushReplacement跳转,而应通过根容器管理页面切换,保持导航栏始终在页面栈的根位置,避免状态丢失。
解决方案

1. 重构页面结构,用根容器统一管理导航栏与页面

将底部导航栏放在根页面中,通过条件渲染切换页面,替代Navigator跳转,确保导航栏状态始终稳定。

2. 同步控制器与本地状态

监听NavigationBarController的状态变化,同步更新导航栏的选中索引,避免状态不一致。

3. 修复图标选中状态的视觉区分

修正原代码中图标颜色无差异的问题,明确区分选中与未选中状态。

修改后的完整代码
import 'package:curved_navigation_bar/curved_navigation_bar.dart';
import 'package:flutter/material.dart';
import 'package:rts_mvc_version_1/controllers/bottom_navigation_bar_controller.dart';

import '../../controllers/home_controller.dart';
import '../../models/home_model.dart';
import '../../models/user_repo_model.dart';
import '../../views/home_screen.dart';
import '../../views/ticket_screen.dart';
import '../service/api_client.dart';

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

  @override
  State<RootContainerScreen> createState() => _RootContainerScreenState();
}

class _RootContainerScreenState extends State<RootContainerScreen> {
  final NavigationBarController _controller = NavigationBarController();
  int _currentIndex = 2;

  // 初始化页面所需实例
  final HomeModel homeModel = HomeModel();
  late final HomeController homeController;
  final UserRepository userRepository = UserRepository();
  final ApiClient apiClient = ApiClient();

  @override
  void initState() {
    super.initState();
    homeController = HomeController(homeModel, () => setState(() {}));
    _controller.setIndex(_currentIndex);
    // 监听控制器状态变化,同步本地索引
    _controller.addListener(() {
      if (_currentIndex != _controller.selectedIndex) {
        setState(() {
          _currentIndex = _controller.selectedIndex;
        });
      }
    });
  }

  // 根据当前索引返回对应页面
  Widget _getCurrentPage() {
    switch (_currentIndex) {
      case 0:
        return const Center(child: Text("通知页面"));
      case 1:
        return TicketScreen();
      case 2:
        return HomeScreen(
          homeModel,
          homeController,
          userRepository,
          apiClient,
        );
      case 3:
        return const Center(child: Text("个人中心"));
      case 4:
        return const Center(child: Text("支付页面"));
      default:
        return const SizedBox.shrink();
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _getCurrentPage(),
      bottomNavigationBar: CurvedNavigationBar(
        backgroundColor: Colors.transparent,
        color: const Color(0xFF273989),
        animationDuration: const Duration(milliseconds: 300),
        index: _currentIndex,
        onTap: (index) {
          _controller.setIndex(index);
          setState(() {
            _currentIndex = index;
          });
        },
        items: [
          Icon(
            Icons.notifications,
            color: _currentIndex == 0 ? Colors.yellow : Colors.white,
          ),
          Icon(
            Icons.confirmation_num,
            color: _currentIndex == 1 ? Colors.yellow : Colors.white,
          ),
          Icon(
            Icons.home_filled,
            color: _currentIndex == 2 ? Colors.yellow : Colors.white,
          ),
          Icon(
            Icons.person,
            color: _currentIndex == 3 ? Colors.yellow : Colors.white,
          ),
          Icon(
            Icons.credit_card,
            color: _currentIndex == 4 ? Colors.yellow : Colors.white,
          ),
        ],
      ),
    );
  }
}
关键修改点
  • 根容器设计:新增RootContainerScreen作为导航栏和页面的统一容器,避免页面跳转导致导航栏状态丢失。
  • 页面切换逻辑:通过_getCurrentPage()根据索引渲染对应页面,替代Navigator跳转,保持导航栏始终可见且状态同步。
  • 状态双向同步:监听控制器状态变化,自动更新本地索引,确保控制器与导航栏状态一致。
  • 视觉状态修复:将选中图标改为黄色(可自定义),明确区分选中状态。
  • 冗余代码清理:删除重复的状态设置调用,简化逻辑层级。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:07:42