在 Flutter 中从 API 获取数据

Posted

技术标签:

【中文标题】在 Flutter 中从 API 获取数据【英文标题】:Getting data from an API in flutter 【发布时间】:2021-02-03 14:14:48 【问题描述】:

使用 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');
  

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

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

唯一的问题是他们没有说我应该在代码中的确切位置

您的帮助将不胜感激,

谢谢

注意:我还是个初学者

【问题讨论】:

您不能(也不应该)在initState 方法中处理期货。相反,请使用FutureBuilder 【参考方案1】:

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

FutureBuilder<News>(
   future: fetchNews(),

FutureBuilder<News>(
   future: news,

Here 是一个很好的解释。

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

/* 如果我删除了 toString() 它会给我错误 参数类型“新闻”不能分配给参数类型 '细绳'。 */

这是因为Text 小部件希望他的输入是String 类型而不是News 类型。

【讨论】:

我将保留FutureBuilder 原样并完全删除对news 的任何引用。除非您需要实际操纵未来本身,否则您几乎不需要将其与使用和解包的地方分开存储。

以上是关于在 Flutter 中从 API 获取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中从 API 获取 JSON 数据

Flutter中从api获取数据时出错

Flutter中从API获取数据时出现格式异常

http包在flutter中从api获取错误的图像url

如何在 Flutter 中从 SQLite 获取数据?

如何在flutter中从云Firestore中获取数据?