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

Flutter使用自定义类的FutureBuilder报length调用null错误如何解决

问题根因
  1. EntertainerEvent.fromJson 缺少必要的类型转换逻辑:JSON解析返回的StartDate、EndDate默认是字符串类型,直接赋值给DateTime类型的字段会抛出类型转换异常;数值类字段如果后台返回类型和声明类型不匹配(比如费用字段后台返回int但你声明为double)也会触发异常。最终会导致fetchEvents方法执行失败,snapshot.data为null。
  2. FutureBuilder的逻辑存在漏洞:仅通过connectionState判断是否加载完成,没有处理请求错误、数据为空的场景,直接对可能为null的snapshot.data调用.length触发报错。
    你之前用dynamic类型时没有强类型校验,解析异常不会直接触发崩溃,所以能运行,切换到自定义类后强类型检查生效,问题就暴露了。
解决方案

步骤1:修复EntertainerEvent.fromJson的类型转换逻辑

factory EntertainerEvent.fromJson(Map<String, dynamic> event) {
  return EntertainerEvent(
    eventId: event['EventID'] as int,
    entertainerId: event['EntertainerID'] as int,
    eventTypeId: event['EventTypeID'] as int,
    categoryId: event['CategoryID'] as int,
    eventName: event['EventName'] as String,
    description: event['Description'] as String,
    imagePoster: event['ImagePoster'] as String,
    location: event['Location'] as String,
    // 将字符串格式的日期转换为DateTime类型
    startDate: DateTime.parse(event['StartDate'] as String),
    endDate: DateTime.parse(event['EndDate'] as String),
    // 统一将数值类型转换为double,避免int转double报错
    entreeFee: (event['EntryFee'] as num).toDouble(),
  );
}

如果接口字段可能返回null,可改用as?加默认值的写法避免崩溃,示例:eventId: event['EventID'] as int? ?? 0

步骤2:优化FutureBuilder的状态判断逻辑

优先处理加载中、错误状态,再处理正常数据场景,避免对null值调用.length:

@override
Widget build(BuildContext context) {
  return FutureBuilder<List<EntertainerEvent>>(
    future: _fetchEvents,
    builder: (BuildContext context, AsyncSnapshot<List<EntertainerEvent>> snapshot) {
      // 加载中状态
      if (snapshot.connectionState == ConnectionState.waiting) {
        return SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) => const Center(child: CircularProgressIndicator()),
            childCount: 1,
          ),
        );
      }
      // 加载错误状态
      if (snapshot.hasError) {
        return SliverList(
          delegate: SliverChildBuilderDelegate(
            (context, index) => Center(child: Text('加载失败:${snapshot.error}')),
            childCount: 1,
          ),
        );
      }
      // 正常加载完成,处理数据
      final List<EntertainerEvent> eventList = snapshot.data ?? [];
      return SliverList(
        delegate: SliverChildBuilderDelegate((context, index) {
          final currentEvent = eventList[index];
          // 此处编写你的列表项布局逻辑
          return Text(currentEvent.eventName);
        }, childCount: eventList.length),
      );
    },
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:00:02