Flutter 中如何在 ListView.builder 内仅修改选中项的文本颜色
问题根因
- 父组件仅存储了选中的语言值,未维护全局选中索引状态,传递给子组件的
isSelected仅为当前项的索引,无法判断是否处于选中状态 - 子组件内部定义的
_selectedIndex = 0为固定值,和全局选中状态完全无关,颜色判断逻辑失效
修改方案
第一步:调整父组件逻辑
在父组件State中新增全局选中索引变量,点击时同步更新选中索引与语言值,将当前项索引、全局选中索引同时传递给子组件:
// 父组件State类中新增变量,初始值可根据默认选中项调整 int _selectedLangIndex = 0; // ListView.builder部分修改后代码 Expanded( flex: 6, child: ListView.builder( itemCount: languageValue.length, shrinkWrap: true, scrollDirection: Axis.vertical, physics: const BouncingScrollPhysics(), itemBuilder: (ctx, index) { LanguageCode lang = languageValue[index]; return _LanguageItemSelection( languageName: lang.value, currentIndex: index, selectedIndex: _selectedLangIndex, onLanguageSelect: () { setState(() { _selectedLangIndex = index; _langValue = lang.value!; }); debugPrint('Language Value => ${lang.code}'); }, ); }, ), ),
第二步:调整子组件逻辑
删除子组件内部无用的固定_selectedIndex变量,直接通过传入的当前项索引和全局选中索引对比判断颜色:
class _LanguageItemSelection extends StatelessWidget { const _LanguageItemSelection({ Key? key, this.languageName, this.onLanguageSelect, required this.currentIndex, required this.selectedIndex, }) : super(key: key); final String? languageName; final VoidCallback? onLanguageSelect; final int currentIndex; final int selectedIndex; @override Widget build(BuildContext context) { debugPrint('index => $currentIndex'); return Column( children: [ const SizedBox(height: 5), InkWell( onTap: onLanguageSelect, child: Text( languageName!, textAlign: TextAlign.center, style: TextStyle( fontSize: 20, color: currentIndex == selectedIndex ? Colors.blue : Colors.black, ), ), ), const SizedBox(height: 5), const Divider( color: Colors.grey, thickness: 0.8, ), ], ); } }
实现逻辑说明
全局选中状态统一由父组件维护,点击项时更新状态触发列表重绘,每个子项接收最新的选中索引后和自身索引对比,匹配时显示选中色,否则保持黑色。
内容的提问来源于stack exchange,提问作者Mustafa Shaikh
相关产品推荐
相关产品推荐

