ios - 首次加载应用程序时,Flutter 中对 API 的调用不会加载所需的 JSON - Flutter

标签 ios api dart cross-platform flutter

我最近在学习用 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 函数。

当我第一次运行应用程序时。图片无法加载并抛出错误 enter image description here

好吧,但是在我点击 Visual Studio Code 调试器控制台上的刷新按钮之后 enter image description here

代码将运行并提供所需的输出。 enter image description here

所以问题是第一次加载应用程序时,它总是抛出一个错误,指出 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/

相关文章:

iOS BLE 蓝牙 - 发送/接收十六进制数据

ios - iOS:调整UIImage大小的问题

ios - 将 EFCircularSlider 的值更新为 UILabel

java - 如何在 Spring Boot Restful 中更改大量数据(更新多个数据)

python - 添加到标准 Python API 中涉及什么?

ios - 核心数据 : Expression tree is too large

mysql - 如何在 mysql 中将表行显示为列

dart - 中断 Dart Futures 链的最佳方式?

dart - 如何使用Dart和网络以60fps的速度驱动动画循环?

Flutter easy_localization 和 intl 版本解决失败