首页 > 解决方案 > 如何从 JSON 中生成第二个屏幕的列表?

问题描述

我正在尝试从 JSON 中的值创建一个列表。我可以得到长度,但不能得到数据。我的主要目标是根据它们的受欢迎程度创建一个项目列表。

        child: Row(
            children: [
              ...List.generate(
                "items"[0].length,
                (index) {
                  if (["items"][index].isPopular) {   // here I want to generate a list for the value isPopular
                    return BreakfastCard(breakfast: ('items'[0] as Map<String, dynamic>[index]); // Here I want to call the function from other screen
                  }

当我尝试将代码更改为此

                "items"[0].length,
                (index) {
                  if (["items"][index][isPopular]) { // the error here is *Conditions must have a static type of 'bool'.*
                    return BreakfastCard(breakfast: ['items'][0][index]); // the error here is *The argument type 'String' can't be assigned to the parameter type 'Breakfast'.*

JSON数据是这样的

{ 
    "items":[{
      
      "id": 1,
      "rating": "0.0",
      "images": [
        "assets/images/cilantro.png"
          ],
      "title": "Cilantro and Kale Pesto Toast with a Fried Egg",
      "time": 15,
      "description": "Sliced bread is the perfect blank canvas, ready to be loaded up with virtuous ingredients.",
    " rating": "4.8",
      "isFavorite": false,
      "isPopular": true,
      
    }]
  }

这是我的卡代码。在这部分中,没有错误,它显示了我想要的。

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';

import '../constants.dart';
import '../size_config.dart';

class BreakfastCard extends StatefulWidget {

    BreakfastCard({
    Key? key,
    this.width = 140,
    this.aspectRetio = 1.02,
    required this.breakfast,
  }) : super(key: key);

  final double width, aspectRetio;
  Breakfast breakfast;

  @override
  _BreakfastCardState createState() => _BreakfastCardState();
}
 
class _BreakfastCardState extends State<BreakfastCard> {
  @override
  Widget build(BuildContext context) {

        Future<String> _loadloadBreakfastAsset() async {
    return await rootBundle.loadString('assets/breakfast.json');
  }


Future<BreakfastCard> loadBreakfast() async {
  String jsonAddress = await _loadloadBreakfastAsset();
  final jsonResponse = json.decode(jsonAddress);
  // This now updates the breakfast property in the main class.
  widget.breakfast = Breakfast.fromJson(jsonResponse);

  // This return value is thrown away, but this line is necessary to 
  // resolve the Future call that FutureBuilder is waiting on.
  return Future<BreakfastCard>.value();
}


    SizeConfig().init(context);
    return FutureBuilder(
      future: loadBreakfast(),
      builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
      return Padding(
        padding: EdgeInsets.only(left: getProportionateScreenWidth(20)),
        child: SizedBox(
          width: getProportionateScreenWidth(140),
          child: GestureDetector(
            onTap: (){},
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                AspectRatio(
                  aspectRatio: 1.02,
                  child: Container(
                    padding: EdgeInsets.all(getProportionateScreenWidth(20)),
                    decoration: BoxDecoration(
                      color: kSecondaryColor.withOpacity(0.1),
                      borderRadius: BorderRadius.circular(15),
                    ),
                    child: Hero(
                      tag: widget.breakfast.id.toString(),
                      child: Image.asset(widget.breakfast.images[0]),
                    ),
                  ),
                ),
                const SizedBox(height: 10),
                Text(
                  widget.breakfast.title,
                  style: const TextStyle(color: Colors.black),
                  maxLines: 2,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      "${widget.breakfast.calories} cal |",
                      style: TextStyle(
                        fontSize: getProportionateScreenWidth(18),
                        fontWeight: FontWeight.bold,
                        color: kPrimaryColor,
                      ),
                    ),
    
                    Text(
                      "${widget.breakfast.time} min",
                      style: TextStyle(
                        fontSize: getProportionateScreenWidth(18),
                        fontWeight: FontWeight.w600,
                        color: kPrimaryColor,
                      ),
                    ),
                    InkWell(
                      borderRadius: BorderRadius.circular(50),
                      onTap: () { widget.breakfast.isFavorite = !widget.breakfast.isFavorite;},
                      child: Container(
                        padding: EdgeInsets.all(getProportionateScreenWidth(8)),
                        height: getProportionateScreenWidth(28),
                        width: getProportionateScreenWidth(28),
                        child: SvgPicture.asset(
                          "assets/icons/Heart Icon_2.svg",
                          color: widget.breakfast.isFavorite
                              ? const Color(0xFFFF4848)
                              : const Color(0xFFDBDEE4),
                        ),
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        ),
      );
    }
    );
    
  


    
  }
}

我的问题就在这里。将在哪里生成列表。我是新来的,我很难解决这个问题。在这里,我可以正确地创建一个函数来从早餐卡中获取数据。

import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:fema/components/breakfast_card.dart';
import 'package:fema/models/Breakfast.dart';
import 'package:flutter/services.dart';
import '../../../size_config.dart';
import 'section_title.dart';

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

  @override
  Widget build(BuildContext context) {
            Future<String> _loadloadBreakfastAsset() async {
    return await rootBundle.loadString('assets/breakfast.json');
  }

Future<Breakfast> loadBreakfast() async {
  String jsonAddress = await _loadloadBreakfastAsset();
  Map<String,dynamic> map = json.decode(jsonAddress);
  List<dynamic> items = map["items"];
  // This return value is thrown away, but this line is necessary to 
  // resolve the Future call that FutureBuilder is waiting on.
  return Future<Breakfast>.value();
}

      return FutureBuilder(
      future: loadBreakfast(),
      builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
        return Column(
          children: [
            Padding(
              padding:
                  EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
              child: SectionTitle(title: "BREAKFAST", press: () {}),
            ),
            SizedBox(height: getProportionateScreenWidth(20)),
            SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: [
                  ...List.generate(
                    items[0].length,
                    (index) {
                      if (items[index].isPopular) {
                        return BreakfastCard(breakfast: );
                      }
                      return const SizedBox
                          .shrink(); // here by default width and height is 0
                    },
                  ),
                  SizedBox(width: getProportionateScreenWidth(20)),
                ],
              ),
            )
          ],
        );
      });
   
  }
}

标签: jsonflutter

解决方案


您需要先将“项目”放入地图中。您正在尝试使用字符串对象“项目”来填充您的列表。您希望 json 中的数据填充它。

首先将数据放入可用的对象中。

Map<String, dynamic> map = jsonDecode(data);
List<dynamic> items = map["items"];

然后,您可以从该数据中填充您的列表。

child: Row(
        children: [
          ...List.generate(
            items.length,
            (index) {
              if (items[index].isPopular) {
                return BreakfastCard(breakfast: (items[0])); 
              }

您的错误来自尝试不正确地使用 json 数据作为 if 语句的条件。另一个错误是因为您在需要其他东西时尝试将字符串作为早餐对象的参数发送(我不知道那是什么。在我写的时候您没有发布 BreakfastCard 类的样子这个。)

Dart 和 Flutter 文档非常好。试试这个https://flutter.dev/docs/development/data-and-backend/json


推荐阅读