Flutter实现点击复用自定义Widget时高亮选中项的方法
Flutter 多组件单选高亮实现方案
核心实现逻辑和BottomNavigationBar的选中逻辑完全一致:父组件全局维护唯一的选中项标识,子组件根据传入的选中状态渲染对应样式,适配任意数量的复用组件场景,没有冗余代码。
步骤1:改造自定义MyContainer组件
给组件增加选中状态参数,内部根据状态自动切换样式,保持无状态组件的特性,方便任意位置复用:
class MyContainer extends StatelessWidget { final VoidCallback onTap; final bool isSelected; // 支持自定义选中/未选中样式,默认配置对齐需求 final Color selectedColor; final Color unselectedColor; final Color selectedBorderColor; const MyContainer({ super.key, required this.onTap, required this.isSelected, this.selectedColor = Colors.blue, this.unselectedColor = const Color(0xFFE0E0E0), this.selectedBorderColor = Colors.blueAccent, }); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(10), child: GestureDetector( onTap: onTap, child: Container( decoration: BoxDecoration( color: isSelected ? selectedColor : unselectedColor, borderRadius: BorderRadius.circular(20), border: isSelected ? Border.all(width: 2, color: selectedBorderColor) : null, ), ), ), ); } }
步骤2:父组件统一维护选中状态
父组件只需要存储一个当前选中项的唯一索引(或自定义ID),点击时更新这个值即可自动触发UI刷新,不需要给每个组件单独写状态逻辑:
class _HomeScreenState extends State<HomeScreen> { // 存储当前选中的组件索引,-1代表初始状态无选中项,可按需设置默认选中值 int selectedIndex = -1; @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Expanded( child: Row( children: [ Expanded(child: _buildSelectableContainer(0)), Expanded(child: _buildSelectableContainer(1)), ], ), ), Expanded(child: _buildSelectableContainer(2)), // 组件数量多的场景直接用循环生成即可,无需手写重复代码 // ...List.generate(100, (index) => Expanded(child: _buildSelectableContainer(index))) ], ), ); } // 抽离公共构建方法,减少重复模板代码 Widget _buildSelectableContainer(int itemIndex) { return MyContainer( isSelected: selectedIndex == itemIndex, onTap: () { setState(() { // 点击后更新选中索引,全局仅当前点击项为选中态 selectedIndex = itemIndex; }); }, ); } }
方案优势
- 逻辑清晰:和系统组件单选逻辑完全对齐,没有黑魔法,后续维护成本低
- 复用性强:MyContainer是纯展示无状态组件,任意页面需要同类交互都可以直接用
- 适配大规模场景:哪怕是上百个同类组件,只需要修改循环的生成数量,不需要重复写组件调用代码,改样式只需要调整MyContainer的默认配置
- 性能开销低:状态更新时仅重新构建状态变化的组件,没有多余的性能损耗
如果是不规则布局、需要非数字作为唯一标识的场景,只需要把
selectedIndex的类型替换为你需要的ID类型(比如String),判断逻辑保持不变即可。
内容的提问来源于stack exchange,提问作者Irfan Ganatra
相关产品推荐
相关产品推荐

