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

Flutter开发:使用ListView.separated布局时遇空值检查运算符错误

解决Flutter中TextOverflow.ellipsis触发空检查错误的问题

错误根源分析

你的错误核心是不安全的空值强制解包和未处理API返回的空字段:

  1. snapshot.data!、snapshot.data!.articles!直接用!强制解包,若API请求失败、返回数据为空或articles字段为null,会直接触发空检查错误。
  2. data.title可能为null,直接插值到Text中会显示"null"字符串,不符合预期。
  3. TextOverflow.ellipsis未配合maxLines使用,该属性仅在文本超出指定行数时生效,否则省略逻辑不会触发。

修正后的代码

import 'dart:convert';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:sizer/sizer.dart';

import 'news_api_get_res_model.dart';

class NewsHomeScreen extends StatelessWidget {
  const NewsHomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<NewsApiGetResModel>(
        future: getNewsData(),
        builder: (context, AsyncSnapshot<NewsApiGetResModel> snapshot) {
          // 处理请求错误状态
          if (snapshot.hasError) {
            return Center(child: Text('请求失败: ${snapshot.error}'));
          }
          // 处理加载状态
          if (snapshot.connectionState == ConnectionState.waiting) {
            return const Center(child: CircularProgressIndicator());
          }
          // 安全获取数据,避免强制解包
          final newsData = snapshot.data;
          final articles = newsData?.articles ?? [];

          return ListView.separated(
            itemCount: articles.length,
            itemBuilder: (context, index) {
              final data = articles[index];
              return Padding(
                padding: EdgeInsets.symmetric(horizontal: 5.w),
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // 处理urlToImage为空的情况
                    Container(
                      height: 30.w,
                      width: 30.w,
                      child: Image.network(
                        data.urlToImage ?? 'https://i.pinimg.com/564x/0f/37/10/0f37109d0cc005766e5f9e625467d884.jpg',
                        fit: BoxFit.cover,
                        errorBuilder: (context, error, stackTrace) {
                          return const Icon(Icons.broken_image);
                        },
                      ),
                    ),
                    Flexible(
                      child: Padding(
                        padding: EdgeInsets.only(left: 2.w),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            Text(
                              data.title ?? '无标题',
                              overflow: TextOverflow.ellipsis,
                              maxLines: 2, // 配合ellipsis指定行数
                              style: const TextStyle(fontWeight: FontWeight.bold),
                            ),
                            SizedBox(height: 1.h),
                            Text(
                              data.description ?? '无描述',
                              overflow: TextOverflow.ellipsis,
                              maxLines: 3,
                              style: TextStyle(color: Colors.grey[600]),
                            ),
                          ],
                        ),
                      ),
                    )
                  ],
                ),
              );
            },
            separatorBuilder: (context, index) => const Divider(thickness: 2),
          );
        },
      ),
    );
  }
}

Future<NewsApiGetResModel> getNewsData() async {
  try {
    http.Response response = await http.get(Uri.parse(
        'https://newsapi.org/v2/everything?q=tesla&from=2022-10-11&sortBy=publishedAt&apiKey=6c5a2cd029a44eb186c8640325bd2901'));
    
    if (response.statusCode != 200) {
      throw Exception('请求错误,状态码: ${response.statusCode}');
    }

    var result = jsonDecode(response.body);
    NewsApiGetResModel newsApiGetResModel = NewsApiGetResModel.fromJson(result);
    log('${newsApiGetResModel.status}');

    return newsApiGetResModel;
  } catch (e) {
    log('获取新闻数据失败: $e');
    rethrow; // 将错误抛给FutureBuilder处理
  }
}

关键修正点

  • 安全处理空值:用??运算符为可能为空的字段设置默认值,彻底避免!强制解包的风险。
  • 完善状态处理:在FutureBuilder中增加错误状态判断,请求失败时显示友好提示。
  • Text属性配合:给使用TextOverflow.ellipsis的Text添加maxLines,确保省略逻辑正常生效。
  • 图片错误处理:为Image.network添加errorBuilder,图片加载失败时显示占位图标。
  • API请求容错:在getNewsData中增加状态码判断和异常捕获,避免请求失败时直接崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 07:05:49