0

使用 API 获取数据

我的代码

class _MyAppState extends State<MyApp> {
  Future<News> news;

  @override
  void initState() {
    super.initState();
    news = fetchNews();
  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: 
      Container(
        color: Colors.white24,
        child:
        Center(child:
        FutureBuilder<News>(
  future: fetchNews(),
  builder: (context, snapshot) {
    if (snapshot.hasData) {

        /* here if I removed toString() it gives me error
         The argument type 'News' can't be assigned to the parameter type 
         'String'. */ 

       return Text(snapshot.data.toString());
    } else if (snapshot.hasError) {
      return Text("${snapshot.error}");
    }

    // By default, show a loading spinner.
    return CircularProgressIndicator();
            },
           ),
          ),
         )
        );
       }
      }
News newsFromJson(String str) => News.fromJson(json.decode(str));

String newsToJson(News data) => json.encode(data.toJson());

class News {
    News({
        this.status,
        this.totalResults,
        this.articles,
    });

    String status;
    int totalResults;
    List<Article> articles;

    factory News.fromJson(Map<String, dynamic> json) => News(
        status: json["status"],
        totalResults: json["totalResults"],
        articles: List<Article>.from(json["articles"].map((x) => Article.fromJson(x))),
    );

    Map<String, dynamic> toJson() => {
        "status": status,
        "totalResults": totalResults,
        "articles": List<dynamic>.from(articles.map((x) => x.toJson())),
    };
}

class Article {
    Article({
        this.source,
        this.author,
        this.title,
        this.description,
        this.url,
        this.urlToImage,
        this.publishedAt,
        this.content,
    });

    Source source;
    String author;
    String title;
    String description;
    String url;
    String urlToImage;
    DateTime publishedAt;
    String content;

    factory Article.fromJson(Map<String, dynamic> json) => Article(
        source: Source.fromJson(json["source"]),
        author: json["author"] == null ? null : json["author"],
        title: json["title"],
        description: json["description"] == null ? null : json["description"],
        url: json["url"],
        urlToImage: json["urlToImage"] == null ? null : json["urlToImage"],
        publishedAt: DateTime.parse(json["publishedAt"]),
        content: json["content"],
    );

    Map<String, dynamic> toJson() => {
        "source": source.toJson(),
        "author": author == null ? null : author,
        "title": title,
        "description": description == null ? null : description,
        "url": url,
        "urlToImage": urlToImage == null ? null : urlToImage,
        "publishedAt": publishedAt.toIso8601String(),
        "content": content,
    };
}

class Source {
    Source({
        this.id,
        this.name,
    });

    dynamic id;
    String name;

    factory Source.fromJson(Map<String, dynamic> json) => Source(
        id: json["id"],
        name: json["name"],
    );

    Map<String, dynamic> toJson() => {
        "id": id,
        "name": name,
    };
}

Future<News> fetchNews() async {
  final response = await http.get('My-Api');

  if (response.statusCode == 200) {
    
    return News.fromJson(jsonDecode(response.body));
  } else {
    
    throw Exception('Failed to load album');
  }
}

当我运行此代码时,输​​出是:“新闻”的实例

我搜索了互联网,发现大多数解决方案都说我必须添加等待。

唯一的问题是他们没有说我应该把它准确地放在代码中的什么地方

您的帮助将不胜感激,

谢谢

注意:我还是个初学者

4

1 回答 1

0

您无需添加await. 您的代码工作正常。我唯一要改变的是

FutureBuilder<News>(
   future: fetchNews(),

FutureBuilder<News>(
   future: news,

是一个很好的解释。

你的输出Instance of 'News'是正确的。这是model您为网络调用的输出声明的。您现在可以访问它的属性(statustotalResultsarticles

/* 这里如果我删除了 toString() 它会给我错误参数类型“新闻”不能分配给参数类型“字符串”。*/

那是因为Text小部件希望他的输入是 typString而不是 type News

于 2020-10-20T17:51:03.210 回答