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

Flutter中如何从JSON生成列表并传递给自定义BreakfastCard组件

Flutter本地JSON解析及横向列表实现方案

前置前提

默认你已在项目中添加本地JSON文件到资源目录,且已完成BreakfastCard的基础UI布局开发。

问题1:isPopular判断报"Conditions must have a static type of 'bool'"错误

原因

JSON解析后字段默认是dynamic类型,未明确声明为bool类型,直接用于条件判断触发类型校验失败。

修复方案

定义强类型Breakfast模型类,解析时明确指定字段类型并做空值兜底:

class Breakfast {
  final String name;
  final String imagePath;
  final bool isPopular;
  // 可根据需求补充其他字段

  Breakfast({
    required this.name,
    required this.imagePath,
    required this.isPopular,
  });

  factory Breakfast.fromJson(Map<String, dynamic> json) {
    return Breakfast(
      name: json['name'] as String? ?? '',
      imagePath: json['imagePath'] as String? ?? '',
      // 明确转bool类型,空值默认设为false避免异常
      isPopular: json['isPopular'] as bool? ?? false,
    );
  }
}

问题2:传参报"The argument type 'String' can't be assigned to the parameter type 'Breakfast'"错误

原因

BreakfastCard组件声明的入参是Breakfast实体类型,调用时传入了单独的字符串字段导致类型不匹配。

修复方案

确认BreakfastCard的入参声明为Breakfast类型,调用时直接传实体:

class BreakfastCard extends StatelessWidget {
  final Breakfast breakfast;
  const BreakfastCard({super.key, required this.breakfast});

  @override
  Widget build(BuildContext context) {
    // 原有布局逻辑直接通过breakfast.xxx取对应字段即可
    return Container(
      margin: const EdgeInsets.only(right: 16),
      width: 120,
      child: Column(
        children: [
          Image.asset(breakfast.imagePath, height: 100, fit: BoxFit.cover),
          const SizedBox(height: 8),
          Text(breakfast.name),
        ],
      ),
    );
  }
}

问题3:解析得到的items数组无法在List.generate中正常调用

原因

解析后的items默认是dynamic类型数组,未转为List<Breakfast>强类型数组,无法直接遍历生成组件。

修复步骤

  1. 首先在pubspec.yaml中声明JSON资源路径:
flutter:
  assets:
    - assets/data/breakfast.json # 替换为你的实际JSON文件路径
  1. 封装JSON读取、解析、筛选逻辑:
import 'dart:convert';
import 'package:flutter/services.dart';

Future<List<Breakfast>> getPopularBreakfasts() async {
  // 读取本地JSON文件
  final jsonStr = await rootBundle.loadString('assets/data/breakfast.json');
  final jsonData = json.decode(jsonStr);
  // 转强类型列表
  List<Breakfast> allItems = (jsonData['items'] as List).map((item) => Breakfast.fromJson(item)).toList();
  // 筛选isPopular为true的条目
  return allItems.where((item) => item.isPopular).toList();
}
  1. 用FutureBuilder渲染横向滚动列表:
Widget buildPopularBreakfastSection() {
  return FutureBuilder<List<Breakfast>>(
    future: getPopularBreakfasts(),
    builder: (context, snapshot) {
      if (snapshot.connectionState == ConnectionState.done && snapshot.hasData) {
        final popularList = snapshot.data!;
        return SizedBox(
          height: 160, // 按需调整卡片高度
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            padding: const EdgeInsets.symmetric(horizontal: 16),
            itemCount: popularList.length,
            itemBuilder: (context, index) {
              return BreakfastCard(breakfast: popularList[index]);
            },
          ),
        );
      } else if (snapshot.hasError) {
        return const Text('数据加载失败');
      }
      return const CircularProgressIndicator();
    },
  );
}

注意事项

  • JSON文件中isPopular字段直接写true/false布尔值,不要加引号变成字符串类型
  • 所有JSON解析步骤都要做类型转换和空值兜底,避免运行时异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:15:03