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

如何根据当前页面动态设置BottomAppBar中图标的颜色

解决BottomAppBar根据当前页面切换图标颜色的问题

你原来的判断逻辑route == ScreenA()是错误的——ModalRoute.of(context)返回的是路由对象(ModalRoute实例),而ScreenA()是页面Widget实例,两者类型完全不同,永远不会相等。下面给出两种可行的解决方案:

方案一:利用路由名称判断

给每个页面的路由设置唯一名称,通过判断当前路由名称切换图标颜色,同时监听路由变化触发Bar重建:

class Bar extends StatefulWidget {
  const Bar({super.key});
  
  @override
  State<Bar> createState() => _BarState();
}

class _BarState extends State<Bar> {
  @override
  void initState() {
    super.initState();
    // 监听路由变化,切换页面时触发Bar重建
    Navigator.of(context).addListener(() {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    final currentRoute = ModalRoute.of(context);
    return SafeArea(
      child: BottomAppBar(
        color: Colors.white,
        child: Row(
          mainAxisSize: MainAxisSize.max,
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: <Widget>[
            IconButton(
              onPressed: () => Navigator.of(context)
                  .push(MaterialPageRoute(
                builder: (context) => const ScreenA(),
                settings: const RouteSettings(name: '/screenA'), // 设置路由名称
              )),
              icon: Icon(
                Icons.home,
                color: currentRoute?.settings.name == '/screenA' ? Colors.white : Colors.grey,
              ),
            ),
            IconButton(
              onPressed: () => Navigator.of(context)
                  .push(MaterialPageRoute(
                builder: (context) => const ScreenB(),
                settings: const RouteSettings(name: '/screenB'), // 设置路由名称
              )),
              icon: Icon(
                Icons.settings,
                color: currentRoute?.settings.name == '/screenB' ? Colors.white : Colors.grey,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

// 示例页面
class ScreenA extends StatelessWidget {
  const ScreenA({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Screen A')),
      bottomNavigationBar: const Bar(),
    );
  }
}

class ScreenB extends StatelessWidget {
  const ScreenB({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Screen B')),
      bottomNavigationBar: const Bar(),
    );
  }
}

方案二:通过页面类型判断

直接判断当前页面的运行时类型,无需设置路由名称,同样需要监听路由变化:

修改Bar中的build方法逻辑:

@override
Widget build(BuildContext context) {
  // 获取当前页面的类型
  final currentPageType = context.widget.runtimeType;
  return SafeArea(
    child: BottomAppBar(
      color: Colors.white,
      child: Row(
        mainAxisSize: MainAxisSize.max,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          IconButton(
            onPressed: () => Navigator.of(context)
                .push(MaterialPageRoute(builder: (context) => const ScreenA())),
            icon: Icon(
              Icons.home,
              color: currentPageType == ScreenA ? Colors.white : Colors.grey,
            ),
          ),
          IconButton(
            onPressed: () => Navigator.of(context)
                .push(MaterialPageRoute(builder: (context) => const ScreenB())),
            icon: Icon(
              Icons.settings,
              color: currentPageType == ScreenB ? Colors.white : Colors.grey,
            ),
          ),
        ],
      ),
    ),
  );
}

注意:这种方式依赖页面的runtimeType,如果页面有子类或开启代码混淆后类型名称变化,可能会失效,适合简单场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 19:17:40