如何根据当前页面动态设置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
相关产品推荐
相关产品推荐

