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

Flutter手势处理抛出ArgumentError,点击按钮更新列表求助

Flutter手势处理触发ArgumentError错误分析与解决

错误根源

  1. 未初始化的索引变量:_WidgetButtonDayState中声明的index变量从未赋值,始终为null,点击按钮时执行testSelectedDays[index] = isSelected会直接抛出ArgumentError,因为列表不接受null作为索引。
  2. 状态管理逻辑错误:每个WidgetButtonDay实例都单独维护自己的testSelectedDays列表,无法实现跨按钮的选中状态共享,完全偏离了记录用户选中日期的需求。
  3. 空回调风险:第一个WidgetButtonDay的onPressed是空函数,虽然不直接触发当前错误,但后续如果依赖该回调逻辑会引发问题。

解决建议

  • 移除_WidgetButtonDayState中冗余的index和testSelectedDays,直接使用父组件传入的widget.index。
  • 将选中状态列表提升到父组件WeekDayV2(改为StatefulWidget),通过回调函数将子组件的点击事件同步到父组件的状态中,实现所有按钮共享同一选中状态。
  • 为onPressed添加空判断,避免空回调调用引发异常。

修正后的完整代码

父组件WeekDayV2(改为Stateful)

class WeekDayV2 extends StatefulWidget {
  @override
  State<WeekDayV2> createState() => _WeekDayV2State();
}

class _WeekDayV2State extends State<WeekDayV2> {
  // 父组件维护共享的选中状态列表
  List<bool> testSelectedDays = List.filled(7, false);

  // 处理子组件点击的回调函数
  void onDayPressed(int index) {
    setState(() {
      testSelectedDays[index] = !testSelectedDays[index];
    });
    print(testSelectedDays);
  }

  // 假设daysOfTheWeek是全局定义的星期列表,比如:
  // final List<String> daysOfTheWeek = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'];

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
      children: List.generate(7, (index) {
        return WidgetButtonDay(
          text: daysOfTheWeek[index].substring(0, 3),
          onPressed: () => onDayPressed(index),
          isSelected: testSelectedDays[index],
          index: index,
        );
      }),
    );
  }
}

子组件WidgetButtonDay

class WidgetButtonDay extends StatelessWidget {
  const WidgetButtonDay({
    Key? key,
    required this.text,
    required this.onPressed,
    required this.index,
    required this.isSelected,
  }) : super(key: key);

  final String text;
  final VoidCallback? onPressed;
  final int index;
  final bool isSelected;

  @override
  Widget build(BuildContext context) {
    return Container(
      height: 30,
      width: 50,
      decoration: BoxDecoration(
        color: isSelected ? Colors.blue : Colors.white,
        borderRadius: BorderRadius.all(Radius.circular(15.0)),
        border: Border.all(color: Colors.black),
      ),
      child: Center(
        child: InkWell(
          child: Text(text),
          onTap: () {
            // 添加空判断,避免空回调调用
            onPressed?.call();
          },
        ),
      ),
    );
  }
}

说明

  • 父组件统一管理选中状态,所有子按钮的选中状态由父组件传递,确保状态一致性。
  • 子组件改为StatelessWidget,因为不再需要维护自身状态,所有状态由父组件控制。
  • 使用List.generate简化按钮列表的生成,避免重复代码。
  • 为onPressed添加空安全调用,提升代码健壮性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 10:45:34