You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中ListViewBuilder下Radio按钮无法正常选中项问题求助

解决Flutter ListView中Radio按钮选中异常的问题

我看了你的代码,问题主要出在两个地方,咱们一步步来修正:

核心问题分析

  1. 状态变量定义位置错误:你把_radioValue放在了build方法内部,这意味着每次调用setState或者组件重绘时,这个变量都会被重置为初始值1,导致选中状态无法正确保存。
  2. Radio的设计逻辑:Radio组件本身就是单选控件——同一groupValue下只能选中一个选项。如果你的需求是多选,那应该用Checkbox而不是Radio;如果确实是要从列表中单选一个选项,那只需要修正状态变量的位置即可。

方案1:实现列表单选(符合Radio的常规用法)

把_radioValue移到State类的成员变量位置,确保状态能在组件生命周期内保持:

class YourWidgetState extends State<YourWidget> {
  // 将状态变量移到这里,初始值设为-1表示未选中任何项
  int _radioValue = -1;

  @override
  Widget build(BuildContext context) { 
    return Container( 
      child: FutureBuilder( 
        future: DocVisitDays(), 
        builder: (BuildContext context, AsyncSnapshot snapshot) { 
          if (snapshot.connectionState != ConnectionState.done) { 
            return CircularProgressIndicator(); 
          } 
          if (snapshot.hasError) { 
            return Text("Something went wrong"); 
          } 
          if (snapshot.hasData) { 
            return ListView.builder( 
              scrollDirection: Axis.vertical, 
              physics: BouncingScrollPhysics(), 
              shrinkWrap: true, 
              itemCount: snapshot.data.length, 
              itemBuilder: (BuildContext context, int index) { 
                return Container( 
                  margin: EdgeInsets.all(10), 
                  padding: EdgeInsets.all(10), 
                  decoration: BoxDecoration( 
                    color: Colors.lightBlue[50], 
                    borderRadius: BorderRadius.all(Radius.circular(12)), 
                    boxShadow: [ 
                      BoxShadow( 
                        color: Colors.grey.withOpacity(0.9), 
                        offset: const Offset(0.0, 5.0), 
                        blurRadius: 3.0, 
                        spreadRadius: 0.5, 
                      ), 
                    ], 
                  ), 
                  child: Row( 
                    children: [ 
                      Radio( 
                        value: index, 
                        groupValue: _radioValue, 
                        onChanged: (value) { 
                          setState(() { 
                            _radioValue = value as int; 
                          }); 
                        }, 
                      ), 
                      Text( 
                        "Visit Day: ${snapshot.data[index].visitDayName},\n Fee: ${snapshot.data[index].fee}, \n Discounted Fee: ${snapshot.data[index].discountedFee}, \n Booking Fee: ${snapshot.data[index].bookingFee} ", 
                        style: TextStyle(fontFamily: 'Poppins'), 
                      ), 
                    ], 
                  ), 
                ); 
              }); 
          } 
          return Text("Error while calling"); 
        }, 
      ), 
    ); 
  }
}

方案2:实现列表多选(每个项独立选中)

如果你的实际需求是允许选中多个列表项,那应该替换Radio为Checkbox,并用一个Map来维护每个项的选中状态:

class YourWidgetState extends State<YourWidget> {
  // 用Map记录每个index的选中状态
  Map<int, bool> _selectedItems = {};

  @override
  Widget build(BuildContext context) { 
    return Container( 
      child: FutureBuilder( 
        future: DocVisitDays(), 
        builder: (BuildContext context, AsyncSnapshot snapshot) { 
          if (snapshot.connectionState != ConnectionState.done) { 
            return CircularProgressIndicator(); 
          } 
          if (snapshot.hasError) { 
            return Text("Something went wrong"); 
          } 
          if (snapshot.hasData) { 
            // 初始化所有项为未选中状态
            for(int i=0; i<snapshot.data.length; i++){
              _selectedItems.putIfAbsent(i, () => false);
            }
            return ListView.builder( 
              scrollDirection: Axis.vertical, 
              physics: BouncingScrollPhysics(), 
              shrinkWrap: true, 
              itemCount: snapshot.data.length, 
              itemBuilder: (BuildContext context, int index) { 
                return Container( 
                  margin: EdgeInsets.all(10), 
                  padding: EdgeInsets.all(10), 
                  decoration: BoxDecoration( 
                    color: Colors.lightBlue[50], 
                    borderRadius: BorderRadius.all(Radius.circular(12)), 
                    boxShadow: [ 
                      BoxShadow( 
                        color: Colors.grey.withOpacity(0.9), 
                        offset: const Offset(0.0, 5.0), 
                        blurRadius: 3.0, 
                        spreadRadius: 0.5, 
                      ), 
                    ], 
                  ), 
                  child: Row( 
                    children: [ 
                      Checkbox( 
                        value: _selectedItems[index], 
                        onChanged: (value) { 
                          setState(() { 
                            _selectedItems[index] = value!; 
                          }); 
                        }, 
                      ), 
                      Text( 
                        "Visit Day: ${snapshot.data[index].visitDayName},\n Fee: ${snapshot.data[index].fee}, \n Discounted Fee: ${snapshot.data[index].discountedFee}, \n Booking Fee: ${snapshot.data[index].bookingFee} ", 
                        style: TextStyle(fontFamily: 'Poppins'), 
                      ), 
                    ], 
                  ), 
                ); 
              }); 
          } 
          return Text("Error while calling"); 
        }, 
      ), 
    ); 
  }
}

内容的提问来源于stack exchange,提问作者Toujo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:22:48