我已经从API中获取了行星的详细信息,即(NOM)卫星数量、重力和密度。我已经将这些详细信息存储在PlanetInfo数组中。我希望使用文本小部件(如Text("${PlanetInfo [1 ]}",样式:文本样式(颜色:颜色。白色))。但它给了我一个错误:范围错误(索引):无效值:有效值范围为空:1
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import 'package:xperience/Models/planets.dart';
class PlanetDescNoMGD extends StatelessWidget {
final Planet planeteee;
List PlanetInfo = [];
getPlanetData() async {
var url =
"https://api.le-systeme-solaire.net/rest/bodies/${planeteee.planetApi}";
final uri = Uri.parse(url);
final response = await http.get(uri);
final body = response.body;
final jsondata = jsonDecode(body);
PlanetInfo.add(jsondata["moons"].length);
PlanetInfo.add(jsondata["gravity"]);
PlanetInfo.add(jsondata["density"]);
}
PlanetDescNoMGD({Key? key, required this.planeteee}) : super(key: key);
@override
void initState() {
this.getPlanetData();
}
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text(
"No. of moons",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.w700),
),
const SizedBox(
height: 12,
),
Text("${PlanetInfo[1]}", style: TextStyle(color: Colors.white))
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text(
"Gravity",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
),
const SizedBox(
height: 12,
),
Text("${PlanetInfo[1]}" + " m/s²",
style: TextStyle(color: Colors.white))
//Text(${num} + " m/s²", style: TextStyle(color: Colors.white))
],
),
Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
const Text(
"Density",
style:
TextStyle(color: Colors.white, fontWeight: FontWeight.w600),
),
const SizedBox(
height: 12,
),
Text("${PlanetInfo[2]}" + " g/cm3",
style: TextStyle(color: Colors.white))
],
),
],
);
}
}
我需要一个解决办法。
2条答案
按热度按时间v8wbuo2f1#
1.您不知道如何使用异步函数。请学习它。您正在向API发出异步请求,并直接尝试使用来自API的响应。这是不可能的。发生的情况是,当调用构建时,您的列表PlanetInfo为空。因此,您将收到错误。
1.无状态小部件没有initState!我发现您试图覆盖不存在的initState。
1.您需要有状态的小部件来使用setState。
1.下面是代码的最小修改工作版本。加载数据后需要使用setState,并更改isLoaded = true。
解决方案如下:
suzh9iv82#
你有两件事要解决。
1.上课。
不要将PlanetInfo用作int列表,充分利用定义类的功能:封装数据并提高可读性。
按如下所示定义类
在州里宣布一个成员。
现在,在fetch调用中创建一个对象,并将其分配给状态成员。
并使用属性显示在窗口小部件中。
1.显示API数据。
您可以使用FutureBuilder等待构建UI,直到API调用完成,或者按照@hiloliddin建议的操作(使用isLoaded成员并基于其值构建UI)。
在您当前的实现中,由于UI是在API调用完成之前构建的,并且列表PlanetInfo为空,因此您会收到该错误。