You need to enable JavaScript to run this app. Flutter开发中SearchScreen构建PredictionTile时触发Text非空断言失败报错
优惠活动
大模型
产品
解决方案
定价
更多

Flutter开发中SearchScreen构建PredictionTile时触发Text非空断言失败报错

报错根因定位

这个异常和Firebase初始化流程无关,本质是PredictionTile组件构建过程中,传入Text组件的字符串参数为null,触发了Flutter Text组件内置的非空断言,常见触发场景包括:

  • Google Places Autocomplete接口返回的预测结构存在字段缺省,部分冷门点位、临时标注的地点会出现description、structured_formatting下的主/副文本字段为null的情况
  • Provider管理的预测列表数据没有经过校验,直接把带null字段的模型对象传给了列表渲染逻辑
  • 异步加载过程中出现状态竞态:空预测条目还未完成过滤,就被Widget树首次构建,提前触发断言
可落地修复方案
  • 第一步:在数据解析层做前置拦截
    从Google Maps Places接口拿到原始响应、转换为项目内部Prediction模型时,提前过滤核心展示字段为null的无效条目,对所有需要展示的字段加默认兜底值,从数据源端避免null值传递
    // 接口数据解析示例
    List<Prediction> _parsePlacesResponse(dynamic rawData) {
      final rawPredictions = rawData?['predictions'] as List? ?? [];
      return rawPredictions.where((item) {
        // 仅保留核心展示字段非空的有效预测
        final hasMainText = item?['structured_formatting']?['main_text'] != null;
        final hasFullDesc = item?['description'] != null;
        return hasMainText && hasFullDesc;
      }).map((item) => Prediction(
        placeId: item['place_id']?.toString() ?? '',
        primaryText: item['structured_formatting']['main_text'].toString(),
        secondaryText: item['structured_formatting']?['secondary_text']?.toString() ?? '',
        fullDesc: item['description'].toString()
      )).toList();
    }
    
  • 第二步:组件渲染层增加兜底防护
    在PredictionTile组件内部,为每一个Text组件的入参加非空判断,即使上游数据出现漏网的null值,也不会触发内置断言:
    // PredictionTile内部Text组件示例
    Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          prediction.primaryText ?? '未知地点',
          style: TextStyle(fontSize: 16),
        ),
        Text(
          prediction.secondaryText ?? '',
          style: TextStyle(fontSize: 12, color: Colors.grey),
        )
      ],
    )
    
  • 第三步:列表渲染逻辑增加空值校验
    在构建预测结果列表时,对列表本身、列表内的单条数据做空判断,避免加载状态下渲染出带null值的组件:
    // 预测列表渲染示例
    ListView.separated(
      padding: EdgeInsets.symmetric(vertical: 8),
      itemCount: searchState.predictions?.length ?? 0,
      separatorBuilder: (_, __) => Divider(height: 1),
      itemBuilder: (context, index) {
        final targetPrediction = searchState.predictions?[index];
        // 单条数据校验,无效条目直接返回空占位组件
        if (targetPrediction == null || targetPrediction.fullDesc.isEmpty) {
          return SizedBox.shrink();
        }
        return PredictionTile(prediction: targetPrediction);
      },
    )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.11 04:24:05