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

Flutter ListView因字段空值不显示数据的解决方法

解决API返回null导致ListView无法显示的问题

问题根源分析

你的代码存在两个核心问题导致ListView无法正常显示:

  • ProductoModelo构造函数中,sub_cat2和sub_cat3被标记为required,但它们是可空类型String?,这种写法容易引发初始化逻辑冲突;
  • FutureBuilder仅处理了snapshot.hasData的成功场景,完全忽略了加载中和请求失败的状态,当API解析出错时,UI没有任何输出。

解决方案

1. 修正模型类构造函数

根据需求选择以下两种方式之一:

方式一:保留可空类型,移除required修饰符

因为sub_cat2和sub_cat3允许为空,无需强制传值:

class ProductoModelo {
  ProductoModelo({
    required this.id,
    required this.sku,
    required this.nombre,
    required this.descripcion,
    required this.destacado,
    required this.visible_en_tienda,
    required this.imagen,
    required this.categoria,
    required this.sub_cat,
    this.sub_cat2, // 移除required
    this.sub_cat3, // 移除required
  });

  String id;
  String sku;
  String nombre;
  String descripcion;
  String destacado;
  String visible_en_tienda;
  String imagen;
  String categoria;
  String sub_cat;
  String? sub_cat2;
  String? sub_cat3;

  // ... fromJson和toJson方法保持不变
}

方式二:改为非空字符串,确保始终有值

如果希望这两个字段永远是非空状态,修改类型并保留required:

class ProductoModelo {
  String id;
  String sku;
  String nombre;
  String descripcion;
  String destacado;
  String visible_en_tienda;
  String imagen;
  String categoria;
  String sub_cat;
  String sub_cat2; // 改为非空String
  String sub_cat3; // 改为非空String

  ProductoModelo({
    required this.id,
    required this.sku,
    required this.nombre,
    required this.descripcion,
    required this.destacado,
    required this.visible_en_tienda,
    required this.imagen,
    required this.categoria,
    required this.sub_cat,
    required this.sub_cat2,
    required this.sub_cat3,
  });

  factory ProductoModelo.fromJson(Map<String, dynamic> json) => ProductoModelo(
        id: json["id"],
        sku: json["sku"],
        nombre: json["nombre"],
        descripcion: json["descripcion"],
        destacado: json["destacado"],
        visible_en_tienda: json["visible_en_tienda"],
        imagen: json["imagen"],
        categoria: json["categoria"],
        sub_cat: json["sub_cat"],
        sub_cat2: json["sub_cat2"] ?? "",
        sub_cat3: json["sub_cat3"] ?? "",
      );

  // ... toJson方法保持不变
}

2. 完善FutureBuilder的状态处理

添加加载中、错误、无数据的UI逻辑,确保所有场景都有响应:

Expanded(
  child: Container(
    child: FutureBuilder(
      future: fetchProductos(),
      builder: (context, snapshot) {
        // 加载中状态
        if (snapshot.connectionState == ConnectionState.waiting) {
          return const Center(child: CircularProgressIndicator());
        }
        // 请求失败状态
        if (snapshot.hasError) {
          return Center(child: Text('加载失败: ${snapshot.error}'));
        }
        // 无数据状态
        if (!snapshot.hasData || (snapshot.data as List).isEmpty) {
          return const Center(child: Text('暂无产品数据'));
        }
        // 数据加载成功
        List<ProductoModelo> filteredList = snapshot.data as List<ProductoModelo>;
        filteredList = filteredList
            .where((element) => element.nombre
                .toLowerCase()
                .contains(_controller.text.toLowerCase()))
            .toList();

        return Padding(
          padding: const EdgeInsets.only(bottom: 20),
          child: ListView.builder(
            itemCount: filteredList.length,
            shrinkWrap: true,
            itemBuilder: (BuildContext context, index) {
              ProductoModelo producto = filteredList[index];
              // ... 原有UI代码保持不变
            },
          ),
        );
      },
    ),
  ),
)

3. 增强网络请求的错误捕获

在fetchProductos中添加异常处理,避免解析失败导致Future崩溃:

Future<List<ProductoModelo>> fetchProductos() async {
  try {
    String url = Constantes().URLProyecto + Constantes().APICarpeta + "get_productos.php";
    final response = await http.get(Uri.parse(url));
    // 检查HTTP状态码
    if (response.statusCode != 200) {
      throw Exception('请求失败,状态码: ${response.statusCode}');
    }
    print("RESPONSE BODY productos" + response.body.toString());
    return productoModeloFromJson(response.body);
  } catch (e) {
    print('加载产品出错: $e');
    rethrow; // 抛出异常让FutureBuilder处理
  }
}

额外优化建议

  • 网络图片添加占位图和错误兜底:
Container(
  height: 80,
  width: 80,
  child: Image.network(
    Constantes().URLProductos + producto.imagen,
    fit: BoxFit.cover,
    placeholder: (context, url) => const CircularProgressIndicator(),
    errorBuilder: (context, error, stackTrace) => const Icon(Icons.image_not_supported),
  ),
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 18:35:41