[英]How to get data from json in flutter
我正在嘗試訪問我的 JSON 數據,但它返回此錯誤。 我已經操縱了我的 JSON 的結構,但似乎沒有任何修復。 我嘗試將[{:[{}]}]
或{:[{}]}
用於 JSON 格式,但錯誤仍然存在。 我想顯示我可以進入容器的數據。
ERROR:
RangeError (RangeError (index): Invalid value: Valid value range is empty: 0)
這是我的代碼。
import 'dart:convert';
import 'package:flutter/material.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 {
BreakfastCard({
Key? key,
this.width = 140,
this.aspectRetio = 1.02,
}) : super(key: key);
final double width, aspectRetio;
@override
_BreakfastCardState createState() => _BreakfastCardState();
}
class _BreakfastCardState extends State<BreakfastCard> {
List breakfast = [];
Future<void> loadBreakfastAsset() async {
final String loadBreakfastAsset = await rootBundle.loadString('assets/data.json');
final breakfast = await json.decode(loadBreakfastAsset);
}
@override
Widget build(BuildContext context) {
SizeConfig().init(context);
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[0]["id"],
child: Image.asset(breakfast[0]["images"]),
),
),
),
const SizedBox(height: 10),
Text(
breakfast[0]["title"],
style: const TextStyle(color: Colors.black),
maxLines: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
"${breakfast[0]["calories"]} cal |",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.bold,
color: kPrimaryColor,
),
),
Text(
"${breakfast[0]["time"]} min",
style: TextStyle(
fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.w600,
color: kPrimaryColor,
),
),
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () { breakfast[0]["isFavorite"] = !breakfast[0]["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[0]["images"]
? const Color(0xFFFF4848)
: const Color(0xFFDBDEE4),
),
),
),
],
)
],
),
),
),
);
}
}
這是我的 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",
"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."
]
}]
}]
這是模型
import 'package:flutter/material.dart';
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'];
//print(streetsFromJson.runtimeType);
// List<String> streetsList = new List<String>.from(streetsFromJson);
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,
);
}
}
當您根據您傳遞的索引調用長度不足的列表時會發生這種情況,即早餐 [0]
你已經創建了一個 Future,但你需要使用 FutureBuilder 來調用它,這樣你的數據就可以傳遞到你的列表中,並且可以在這里訪問早餐 [0]
首先,雖然我們不需要[]
在JSON
數據的外側。
第二個問題來自數據類型。 關於 JSON 建模。 如果仔細觀察, id
在 JSON 上是 String 而在模型類上是int
。 在 JSON 上將id
轉換為 int,
像"id": 1,
一樣,其他字段也一樣,檢查數據類型並基於它創建模型。
第三,它需要使用FutureBuilder
來加載資產的 JSON 並解析它。
它會像
Future<List<Breakfast>> loadBreakfastAsset() async {
final String _loadBreakfastAsset =
await rootBundle.loadString('json/bg.json');
final jsonString = await json.decode(_loadBreakfastAsset)["items"] as List;
final breakfastList = jsonString.map((e) => Breakfast.fromJson(e)).toList();
return breakfastList;
}
你按照我的說明去做。
我正在分享經過測試的代碼片段,您需要檢查並應用到所有人。
class Breakfast {
final int id;
final int time;
final int serving;
final String title;
final List<String> procedure;
Breakfast({
required this.id,
required this.time,
required this.serving,
required this.title,
required this.procedure,
});
factory Breakfast.fromJson(Map<String, dynamic> parsedJson) {
var procedureFromJson = parsedJson['procedure'];
List<String> procedureList = procedureFromJson.cast<String>();
return Breakfast(
title: parsedJson['title'],
serving: parsedJson['serving'],
id: parsedJson['id'],
time: parsedJson['time'],
procedure: procedureList,
);
}
}
class _BreakfastCardState extends State<BreakfastCard> {
Future<List<Breakfast>> loadBreakfastAsset() async {
final String _loadBreakfastAsset =
await rootBundle.loadString('json/bg.json');
final jsonString = await json.decode(_loadBreakfastAsset)["items"] as List;
final breakfastList = jsonString.map((e) => Breakfast.fromJson(e)).toList();
return breakfastList;
}
@override
Widget build(BuildContext context) {
// SizeConfig().init(context);
return FutureBuilder<List<Breakfast>>(
future: loadBreakfastAsset(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text("Got ERR :${snapshot.error}");
} else if (snapshot.hasData) {
final List<Breakfast> breakfast = snapshot.data!;
return Padding(
padding: const EdgeInsets.only(left: (20)),
child: SizedBox(
// width: getProportionateScreenWidth(140),
width: 100,
height: 200,
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[0]["id"],
// child: Image.asset(breakfast[0]["images"]),
// ),
),
),
const SizedBox(height: 10),
Text(
breakfast[0].title,
style: const TextStyle(color: Colors.black),
maxLines: 2,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Text(
// "${breakfast[0].calories} cal |",
// style: TextStyle(
// // fontSize: getProportionateScreenWidth(18),
// fontWeight: FontWeight.bold,
// // color: kPrimaryColor,
// ),
// ),
Text(
"${breakfast[0].time} min",
style: TextStyle(
// fontSize: getProportionateScreenWidth(18),
fontWeight: FontWeight.w600,
// color: kPrimaryColor,
),
),
InkWell(
borderRadius: BorderRadius.circular(50),
onTap: () {
// breakfast[0].isFavorite =
// !breakfast[0].isFavorite;
},
child: Container(
padding: EdgeInsets.all((8)), child: Text("A")),
),
],
)
],
),
),
),
);
}
return Text("...");
});
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.