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

Flutter页面跳转时如何修改BottomBar图标颜色?

解决方案

你的问题核心是每个页面都独立实例化BottomBar,导致选中状态currentTab无法共享,每次跳转都会重置为初始值0。下面提供两种可行的修改方案,优先推荐第一种,更符合底部导航栏的设计逻辑。

方案一:父页面统一管理BottomBar与页面切换(推荐)

将BottomBar和页面切换逻辑放在同一个父页面中,子页面不再单独包含BottomBar,这样状态由父页面统一维护,不会被重置。

步骤1:创建主页面承载BottomBar与页面切换

class MainScreen extends StatefulWidget {
  const MainScreen({Key? key}) : super(key: key);

  @override
  State<MainScreen> createState() => _MainScreenState();
}

class _MainScreenState extends State<MainScreen> {
  // 维护当前选中的tab索引
  int _currentTab = 0;
  // 所有子页面列表(注意索引要和BottomBar的按钮对应)
  final List<Widget> _screens = const [
    HomePage(),
    ShopPage(),
    WalletPage(),
    PeoplePage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // 根据当前选中的tab切换body内容
      body: _screens[_currentTab],
      // 传入当前选中状态和切换回调给BottomBar
      bottomNavigationBar: BottomBar(
        currentTab: _currentTab,
        onTabTap: (index) {
          setState(() {
            _currentTab = index;
          });
        },
      ),
    );
  }
}

步骤2:修改BottomBar为受控组件

将BottomBar改为无状态组件,由父页面传入选中状态和切换回调,不再自行管理状态和页面跳转:

class BottomBar extends StatelessWidget {
  // 接收父页面传入的当前选中索引
  final int currentTab;
  // 接收父页面传入的切换回调
  final Function(int) onTabTap;

  const BottomBar({
    Key? key,
    required this.currentTab,
    required this.onTabTap,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return BottomAppBar(
      shape: const CircularNotchedRectangle(),
      notchMargin: 10,
      child: SizedBox(
        height: 60,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                MaterialButton(
                  minWidth: 40,
                  // 点击时调用父页面的切换回调
                  onPressed: () => onTabTap(0),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.home,
                        // 根据父页面传入的currentTab判断颜色
                        color: currentTab == 0 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
                MaterialButton(
                  minWidth: 40,
                  onPressed: () => onTabTap(1),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.shop,
                        color: currentTab == 1 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
              ],
            ),
            // 右侧Tab按钮
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                MaterialButton(
                  minWidth: 40,
                  onPressed: () => onTabTap(2),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.wallet,
                        color: currentTab == 2 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
                MaterialButton(
                  minWidth: 40,
                  onPressed: () => onTabTap(3),
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.people,
                        color: currentTab == 3 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

步骤3:移除子页面中的BottomBar

删除所有子页面(HomePage、ShopPage等)中的bottomNavigationBar: BottomBar()代码,因为BottomBar现在只在MainScreen中显示。

方案二:用状态管理共享选中状态(保留Navigator跳转场景)

如果必须保留Navigator.push的跳转方式,可以通过状态管理工具(如Provider)共享currentTab状态,让所有BottomBar实例同步选中状态。

步骤1:创建状态管理类

import 'package:flutter/material.dart';

class TabProvider extends ChangeNotifier {
  int _currentTab = 0;

  int get currentTab => _currentTab;

  // 更新选中状态并通知所有监听者
  void setCurrentTab(int index) {
    _currentTab = index;
    notifyListeners();
  }
}

步骤2:在全局注入状态管理

在main.dart中用ChangeNotifierProvider包裹根组件:

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => TabProvider(),
      child: const MyApp(),
    ),
  );
}

步骤3:修改BottomBar使用共享状态

class BottomBar extends StatelessWidget {
  const BottomBar({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 获取共享的状态实例
    final tabProvider = Provider.of<TabProvider>(context);
    return BottomAppBar(
      shape: const CircularNotchedRectangle(),
      notchMargin: 10,
      child: SizedBox(
        height: 60,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                MaterialButton(
                  minWidth: 40,
                  onPressed: () {
                    // 更新共享状态
                    tabProvider.setCurrentTab(0);
                    // 用pushReplacement避免页面栈积累
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(builder: (context) => const HomePage()),
                    );
                  },
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.home,
                        color: tabProvider.currentTab == 0 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
                MaterialButton(
                  minWidth: 40,
                  onPressed: () {
                    tabProvider.setCurrentTab(1);
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(builder: (context) => const ShopPage()),
                    );
                  },
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.shop,
                        color: tabProvider.currentTab == 1 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
              ],
            ),
            // 右侧按钮同理修改
            Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                MaterialButton(
                  minWidth: 40,
                  onPressed: () {
                    tabProvider.setCurrentTab(2);
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(builder: (context) => const WalletPage()),
                    );
                  },
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.wallet,
                        color: tabProvider.currentTab == 2 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
                MaterialButton(
                  minWidth: 40,
                  onPressed: () {
                    tabProvider.setCurrentTab(3);
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(builder: (context) => const PeoplePage()),
                    );
                  },
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Icon(
                        Icons.people,
                        color: tabProvider.currentTab == 3 ? Colors.blue : Colors.grey,
                      ),
                    ],
                  ),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 04:15:35