【问题标题】:how to get the json data in a json file locally in flutter如何在flutter中本地获取json文件中的json数据
【发布时间】:2021-12-24 05:41:48
【问题描述】:

我正在尝试从 json 文件中获取数据。但我做错了。我不知道这有什么问题。希望得到建议或教程。

我得到的错误是:Undefined name 'breakfast'. 然后当我将早餐改为早餐时,我得到了错误:Instance member '...' can't be accessed using static access.Nothing else。我希望得到一个解释。我只是一个新手。我试图在网上寻找问题和解释,但没有解决它。

代码如下:

```import 'dart:convert';

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

import '../constants (2).dart';
import '../constants.dart';
import '../size_config.dart';

class BreakfastCard extends StatefulWidget {

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

  final double`enter code here` width, aspectRetio;
  final Breakfast breakfast;

  @override
  _BreakfastCardState createState() => _BreakfastCardState();
}
 
class _BreakfastCardState extends State<BreakfastCard> {
  @override
  Widget build(BuildContext context) {
    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: breakfast.id.toString(),
                      child: Image.asset(breakfast.images[0]),
                    ),
                  ),
                ),
                const SizedBox(height: 10),
                Text(
                  breakfast.title,
                  style: const TextStyle(color: Colors.black),
                  maxLines: 2,
                ),
                Row(
                  mainAxisAlignment: MainAxisAlignment.spaceBetween,
                  children: [
                    Text(
                      "${breakfast.calories} cal |",
                      style: TextStyle(
                        fontSize: getProportionateScreenWidth(18),
                        fontWeight: FontWeight.bold,
                        color: kPrimaryColor,
                      ),
                    ),
    
                    Text(
                      "${breakfast.time} min",
                      style: TextStyle(
                        fontSize: getProportionateScreenWidth(18),
                        fontWeight: FontWeight.w600,
                        color: kPrimaryColor,
                      ),
                    ),
                    InkWell(
                      borderRadius: BorderRadius.circular(50),
                      onTap: () { breakfast.isFavorite = !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: breakfast.isFavorite
                              ? const Color(0xFFFF4848)
                              : const Color(0xFFDBDEE4),
                        ),
                      ),
                    ),
                  ],
                )
              ],
            ),
          ),
        ),
      );
    }
    );
    
  }
    Future<String> _loadloadBreakfastAsset() async {
    return await rootBundle.loadString('assets/data.json');
  }

  Future loadBreakfast() async {
    String jsonAddress = await _loadloadBreakfastAsset();
    final jsonResponse = json.decode(jsonAddress);
    Breakfast breakfast = Breakfast.fromJson(jsonResponse);

    
  }

}```

这是模型


    class Breakfast {
      final int id, time, serving;
      final String title, description, calories;
      final List <String> procedure;
      final List <String> ingredients;
      final List <String> naturalFacts;
      final List<String> images;
      final double rating;
      bool isFavorite, isPopular;
    
      Breakfast({
        required this.id,
        required this.images,
        this.rating = 0.0,
        this.isFavorite = false,
        this.isPopular = false,
        required this.title,
        required this.time,
        required this.description,
        required this.ingredients,
        required this.procedure,
        required this.naturalFacts,
        required this.calories,
        required this.serving,
      });
    
        factory Breakfast.fromJson(Map<String, dynamic> parsedJson) {
        var procedureFromJson  = parsedJson['procedure'];
        var ingredientsFromJson  = parsedJson['ingredients'];
        var naturalFactsFromJson  = parsedJson['naturalFacts'];
        var imagesFromJson  = parsedJson['images'];
        
        List<String> ingredientsList = ingredientsFromJson.cast<String>();
        List<String> procedureList = procedureFromJson.cast<String>();
        List<String> imagesList = imagesFromJson.cast<String>();
    
        return new Breakfast(
          calories: parsedJson['calories'],
          time: parsedJson['time'],
          title: parsedJson['title'],
          description: parsedJson['description'],
          naturalFacts: parsedJson['naturalFacts'],
          serving: parsedJson['serving'],
          id: parsedJson['id'],
    
          procedure: procedureList,
          ingredients: ingredientsList,
          images: imagesList,
        );
      }
    }

json数据


    [
        {
        "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,
        "calories": "405",
        "serving": 1,
        "naturalFacts": [
          "405 calories",
          "protein 15g",
          "fat 31g",
          "saturated fat 5.8g",
          "carbohydrates 16g",
          "fiber 1.9g",
          "sodium 331mg",
          "cholesterol 189mg"
    
        ],
            "ingredients": [
                "¼ cup packed cilantro",
                "1 cup packed kale leaves",
                "¼ cup extra-virgin olive oil",
                "1 tablespoon white balsamic vinegar",
                "2 tablespoons hulled hemp seeds*",
                "salt",
                "Freshly ground pepper",
                "1 large slice of whole-wheat toast",
                "2 tablespoons unflavored whole-milk Greek yogurt",
                "1 fried egg"
            ],
            "procedure": [
            "Whirl the cilantro, kale leaves, extra-virgin olive oil, white balsamic vinegar, and hemp seeds* until fairly smooth, scraping inside of bowl.",
            "Season with sea salt and freshly ground pepper. Smear a large slice of whole-wheat toast with the yogurt, then with some pesto.",
            "Top with a fried egg and more salt and pepper."
            ]
        }
    ]

【问题讨论】:

    标签: json flutter dart flutter-futurebuilder


    【解决方案1】:

    从我对您的代码的视觉检查来看,我会说首先修复您的 loadBreakfast() 方法。

    您的原始代码...

    Future loadBreakfast() async {
      String jsonAddress = await _loadloadBreakfastAsset();
      final jsonResponse = json.decode(jsonAddress);
      Breakfast breakfast = Breakfast.fromJson(jsonResponse);
    }
    

    Future 是 Dart 对 Promise() 的名称

    如果方法返回一个未来类型会更好。您的方法根本不返回任何内容。当您的 FutureBuilder 调用 loadBreakfast 时,它可能会收到一个空响应并且没有完成任何工作。

    此更改修复了 Future 的退货问题:

    Future<Breakfast> loadBreakfast() async {
      String jsonAddress = await _loadloadBreakfastAsset();
      final jsonResponse = json.decode(jsonAddress);
      // This line is a problem. See my later comments.
      // Breakfast breakfast = Breakfast.fromJson(jsonResponse);
      return Future<Breakfast>.value(Breakfast.fromJson(jsonResponse));
    }
    

    这条线并没有像你想象的那样做。

    Breakfast breakfast = Breakfast.fromJson(jsonResponse);
    

    这声明了一个名为“早餐”的新变量,将解析后的 JSON 的值分配给它,然后该方法结束并丢弃该变量。

    顺便说一句,这是一个依赖副作用的代码示例,您应该重新考虑如何做到这一点。

    没有改变您在方法开始时声明的值。 以下是如何获得您想要的效果。

    我将假设您要将解析的 JSON 返回分配给您在小部件顶部定义的“早餐”属性。如果是这样,你应该这样做。

    首先,将文件底部的两个方法移到_BreakfastCardState类的范围内。

      }<--- move this brace past the end of loadBreakfast()
        Future<String> _loadloadBreakfastAsset() async {
        return await rootBundle.loadString('assets/data.json');
      }
    
      Future loadBreakfast() async {
        String jsonAddress = await _loadloadBreakfastAsset();
        final jsonResponse = json.decode(jsonAddress);
        Breakfast breakfast = Breakfast.fromJson(jsonResponse);
    
        
      }
    

    这将允许这些方法访问 StatefulWiget 范围内的早餐变量。

    现在您想将 loadBreakfast() 更改为这种形式。

    Future<Breakfast> 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<Breakfast>.value(null);
    }
    

    最终的效果应该是 FutureBuilder 等到您解析 JSON 文件并使用解析后的值更新“早餐”,然后解析 Future。

    FutureBuilder 然后调用您的谓词代码,并且返回应该包含您期望的所有值。

    还有一点:在您的 Widget 代码中的任何地方都有“早餐”。将其更改为“widget.breakfast”。

    如果这对您有用,请将其标记为已接受的答案。

    【讨论】:

    • 非常感谢!它似乎有效,但在我家:BreakfastCard(早餐:早餐),似乎第二个“早餐”未定义。我应该放什么?
    • 不确定你在问什么。这是否出现在您发布的代码中?
    猜你喜欢
    • 2014-09-19
    • 2020-03-24
    • 2021-10-24
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    相关资源
    最近更新 更多