Flutter中如何实现ListView.builder生成的按钮仅被点击的那个变色
问题根因
你当前所有按钮共用同一个全局pressAttention状态变量,只要状态更新所有按钮的颜色判断逻辑都会同步生效,自然会出现全选/全不选的联动效果。根据你的使用场景可以选择以下两种解决方案:
方案1:单选模式(仅允许同时选中一个按钮)
用可空整型记录当前选中的按钮索引即可,修改代码如下:
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"]; // 替换原来的bool变量,记录当前选中的索引,初始为null表示没有选中项 int? selectedIndex; Widget build(BuildContext context) { return SafeArea( child: SingleChildScrollView( child: SizedBox( height: MediaQuery.of(context).size.height, child: ListView.builder( shrinkWrap: true, itemCount: litems.length, itemBuilder: (BuildContext ctxt, int index) { return Column( children: [ Container( height: 55.0, width: MediaQuery.of(context).size.width*0.9, child: RaisedButton( child: Text(litems[index]), textColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0), ), // 判断当前索引是否是选中的索引,决定颜色 color: selectedIndex == index ? Colors.green : Colors.grey, onPressed: () => setState(() { // 点击已选中的按钮可以取消选中,不需要的话直接赋值selectedIndex = index即可 selectedIndex = selectedIndex == index ? null : index; }), ), ), SizedBox(height: 20), ], ); }), ), ), ); }
方案2:多选模式(允许同时选中多个按钮)
用布尔数组记录每一个按钮的选中状态:
List<String> litems = ["Counter No 1", "Counter No 2", "Counter No 3", "Counter No 4"]; // 存储每个位置按钮的选中状态 late List<bool> pressStatus; // 初始化状态数组,要写在State类的initState方法里 @override void initState() { super.initState(); pressStatus = List.generate(litems.length, (index) => false); } Widget build(BuildContext context) { return SafeArea( child: SingleChildScrollView( child: SizedBox( height: MediaQuery.of(context).size.height, child: ListView.builder( shrinkWrap: true, itemCount: litems.length, itemBuilder: (BuildContext ctxt, int index) { return Column( children: [ Container( height: 55.0, width: MediaQuery.of(context).size.width*0.9, child: RaisedButton( child: Text(litems[index]), textColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30.0), ), // 取当前索引对应的状态判断颜色 color: pressStatus[index] ? Colors.green : Colors.grey, onPressed: () => setState(() { // 仅修改当前索引对应的状态 pressStatus[index] = !pressStatus[index]; }), ), ), SizedBox(height: 20), ], ); }), ), ), ); }
小提示:RaisedButton已在Flutter 2.0+版本废弃,建议替换为ElevatedButton使用,参数逻辑基本一致
内容的提问来源于stack exchange,提问作者TimeToCode
相关产品推荐
相关产品推荐

