我最近在学习用 flutter 编写代码,并在 iOS 上使用它构建了一个应用程序。因此,我想构建一个涉及其中的 NASA APOD API。
我创建了一个简单的 UI 并设置了一张带有 ImageView 的卡片,它将在从 API 的 JSON 传递 url 后加载图像。
JSON:
{
"copyright": "Panther Observatory",
"date": "2006-04-15",
"explanation": "In this stunning cosmic vista, galaxy M81 is on the left surrounded by blue spiral arms. On the right marked by massive gas and dust clouds, is M82. These two mammoth galaxies have been locked in gravitational combat for the past billion years. The gravity from each galaxy dramatically affects the other during each hundred million-year pass. Last go-round, M82's gravity likely raised density waves rippling around M81, resulting in the richness of M81's spiral arms. But M81 left M82 with violent star forming regions and colliding gas clouds so energetic the galaxy glows in X-rays. In a few billion years only one galaxy will remain.",
"hdurl": "https://apod.nasa.gov/apod/image/0604/M81_M82_schedler_c80.jpg",
"media_type": "image",
"service_version": "v1",
"title": "Galaxy Wars: M81 versus M82",
"url": "https://apod.nasa.gov/apod/image/0604/M81_M82_schedler_c25.jpg" },
现在我从这个 JSON 中获取 URL 并将其转换为字符串并将其传递给 Image.Network
函数。
好吧,但是在我点击 Visual Studio Code 调试器控制台上的刷新按钮之后
所以问题是第一次加载应用程序时,它总是抛出一个错误,指出 url 未定义,但在刷新应用程序后,图像和所有数据都从 API 调用加载。
在这种情况下可能是什么错误。我认为这与 Flutter 上的状态有关。任何帮助表示赞赏。!!
这是代码
import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;
class Home extends StatefulWidget {
@override
StateApodCall createState() => new StateApodCall();
}
class StateApodCall extends State<Home> {
final url = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY";
List resBody;
String imageUrl;
String imageTitle;
Future<String> getAPODData() async{
var res = await http
.get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
var resBody = json.decode(res.body);
print(resBody);
print(resBody["copyright"]);
imageUrl = resBody["hdurl"];
imageTitle = resBody["title"];
print(imageUrl);
return "Success!!";
}
@override
initState() {
super.initState();
this.getAPODData();
}
@override
Widget build(BuildContext context) {
return new Container(
decoration: new BoxDecoration(
gradient: new LinearGradient(
colors: [
const Color(0xFF1ca2e3),
const Color(0xFF1450a3)
],
begin: const FractionalOffset(1.0, 0.5),
end: const FractionalOffset(0.3, 0.1),
stops: [0.0, 0.5],
tileMode: TileMode.clamp
),
),
child: new Scaffold(
backgroundColor: Colors.transparent,
appBar: new AppBar(
backgroundColor: const Color(0xFF124489),
elevation: 20.0,
leading: new IconButton(
icon: new Icon(Icons.menu),
onPressed: () {
}
),
title: new Text(
"APOD",
style: const TextStyle(
color: Colors.white,
fontFamily: 'Poppins',
fontWeight: FontWeight.w600,
fontSize: 34.0
),
),
),
body: new ListView(
children : [
new Card(
elevation: 3.0,
child: new Column(
children: [
new Image.network(
imageUrl,
width: double.infinity,
fit: BoxFit.fitWidth,
),
],
),
),
new Card(
elevation: 2.0,
child: new Text(imageTitle),
),
],
),
)
);
}
}
最佳答案
有多种方法可以解决这个问题。您可以简单地添加一个 ProgressIndicator
,当 API 调用完成时,它会被 ListView
替换。
imageUrl!=null? new ListView(
//build
) : new Center(child:new CircularProgressIndicator()),
不要忘记在设置 url 时添加 setState()
调用
setState((){
imageUrl = resBody["hdurl"];
});
关于ios - 首次加载应用程序时,Flutter 中对 API 的调用不会加载所需的 JSON - Flutter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49956756/