Flutter:InkWell按钮组点击切换时前一个按钮无法恢复原色的问题解决方案
这个问题的核心是每个NavigationButton都在自己的状态类里独立维护颜色状态,它们之间没有任何通信,所以点击新按钮时,旧按钮根本不知道要把颜色改回去。解决办法是把选中状态提升到父组件,让父组件统一管理哪个按钮被选中,这样所有按钮都能根据父组件的状态来更新自己的颜色。
下面是具体的修改步骤和代码:
1. 重构NavigationButton,让它依赖父组件传递的状态
把NavigationButton改成无状态组件,不再自己维护颜色,而是接收父组件传来的isSelected(是否被选中)和点击回调onTap:
class NavigationButton extends StatelessWidget { const NavigationButton({ Key? key, required this.title, required this.isSelected, required this.onTap, }) : super(key: key); final String title; final bool isSelected; final VoidCallback onTap; @override Widget build(BuildContext context) { return Row( mainAxisAlignment: MainAxisAlignment.end, children: [ InkWell( highlightColor: Colors.transparent, splashColor: Colors.transparent, child: Text( title, style: const TextStyle(color: Colors.white, fontSize: 25), ), onTap: onTap, ), const SizedBox(width: 10), Container( width: 10, height: 10, decoration: BoxDecoration( // 根据isSelected切换颜色 color: isSelected ? Colors.red : Colors.white, shape: BoxShape.circle, ), ), ], ); } }
2. 在父组件中维护选中状态,并传递给每个按钮
在包含导航菜单的父组件的状态类里,添加一个变量记录当前选中的按钮索引,然后在构建NavigationButton时,把是否选中的判断和点击回调传进去:
// 父组件的状态类示例 class _ParentWidgetState extends State<ParentWidget> { // 初始值设为-1,表示没有按钮被选中 int _selectedIndex = -1; // 假设_sectionsName是你的菜单标题列表 final List<String> _sectionsName = ['菜单1', '菜单2', '菜单3']; @override Widget build(BuildContext context) { return Container( height: 205, width: 210, padding: const EdgeInsets.only(right: 10), child: Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ for (int index = 0; index < _sectionsName.length; index++) NavigationButton( title: _sectionsName[index], // 判断当前按钮是否是选中的那个 isSelected: index == _selectedIndex, // 点击时更新选中索引 onTap: () { setState(() { _selectedIndex = index; }); }, ) ], ), ); } }
为什么这样能解决问题?
- 父组件统一管理
_selectedIndex,所有按钮的选中状态都依赖这个变量,实现了状态共享。 - 当点击某个按钮时,父组件更新
_selectedIndex并调用setState,所有按钮都会重新构建,根据新的索引判断自己是否应该显示红色,之前选中的按钮会因为index != _selectedIndex自动变回白色。
这样就实现了点击一个按钮变红,其他按钮变回白色的单选效果啦!
内容的提问来源于stack exchange,提问作者user10033434
相关产品推荐
相关产品推荐

