Flutter动态生成ToggleButton点击后颜色不变化问题排查
问题原因
你的核心问题在于选中状态未被持久化存储:
getToggleButttonBars方法内的isSelected是局部变量,每次build执行时,该方法都会重新生成一个全为false的新列表。- 点击按钮时虽然在
setState里修改了局部列表的状态,但setState触发重新build后,方法又会创建新的初始状态列表,之前的修改被覆盖,导致ToggleButtons始终显示初始未选中状态,颜色自然不会变化。
解决方案
将每组ToggleButtons的选中状态存储在State类的成员变量中,而非方法局部变量:
- 在
_MyAppState类中添加与responseArray对应的状态列表:
List<List<bool>> selectedStates = [];
- 在
initState中初始化这个状态列表,每组初始值设为全false:
@override void initState() { responseArray.add(["Very good", "Good", "Poor", "Very Poor"]); responseArray.add(["Good", "Better", "Best"]); responseArray.add(["Yes", "No", "MayBe"]); // 初始化每组选中状态 for (var group in responseArray) { selectedStates.add(List.filled(group.length, false)); } super.initState(); }
- 修改
getToggleButttonBars方法,接收组索引并从成员变量中获取对应状态:
Widget getToggleButttonBars(List<String> responseArray, int groupIndex) { var responses = responseArray; List<Widget> ratingWidgets = []; for (int i = 0; i < responses.length; i++) { ratingWidgets.add(Text(responses[i].toString())); } return Padding( padding: const EdgeInsets.all(8.0), child: ToggleButtons( borderRadius: const BorderRadius.all(Radius.circular(8)), selectedBorderColor: Colors.green, borderColor: Colors.blue, selectedColor: Colors.green, color: Colors.red, isSelected: selectedStates[groupIndex], // 使用成员变量中的状态 children: ratingWidgets, direction: Axis.horizontal, onPressed: (int index) { setState(() { // 修改对应组的选中状态 for (int i = 0; i < selectedStates[groupIndex].length; i++) { selectedStates[groupIndex][i] = i == index; } }); print(selectedStates[groupIndex]); }, )); }
- 在build方法中调用时传入组索引:
for (int i = 0; i < 3; i++) getToggleButttonBars(responseArray[i], i)
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; void main() => runApp(MaterialApp(home: MyApp())); class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { bool spinnerRun = false; List<List<String>> responseArray = []; List<List<bool>> selectedStates = []; // 新增状态存储列表 @override void initState() { responseArray.add(["Very good", "Good", "Poor", "Very Poor"]); responseArray.add(["Good", "Better", "Best"]); responseArray.add(["Yes", "No", "MayBe"]); // 初始化每组的选中状态 for (var group in responseArray) { selectedStates.add(List.filled(group.length, false)); } super.initState(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: ModalProgressHUD( inAsyncCall: spinnerRun, child: Column( children: [ SizedBox( height: 50.0, ), // 传入组索引 for (int i = 0; i < 3; i++) getToggleButttonBars(responseArray[i], i) ], ), ), ); } Widget getToggleButttonBars(List<String> responseArray, int groupIndex) { var responses = responseArray; List<Widget> ratingWidgets = []; for (int i = 0; i < responses.length; i++) { ratingWidgets.add(Text(responses[i].toString())); } return Padding( padding: const EdgeInsets.all(8.0), child: ToggleButtons( borderRadius: const BorderRadius.all(Radius.circular(8)), selectedBorderColor: Colors.green, borderColor: Colors.blue, selectedColor: Colors.green, color: Colors.red, isSelected: selectedStates[groupIndex], children: ratingWidgets, direction: Axis.horizontal, onPressed: (int index) { setState(() { for (int i = 0; i < selectedStates[groupIndex].length; i++) { selectedStates[groupIndex][i] = i == index; } }); print(selectedStates[groupIndex]); }, )); } }
内容的提问来源于stack exchange,提问作者VMi
相关产品推荐
相关产品推荐

