在 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
。您现在可以访问它的属性(status
、totalResults
和 articles
)。
/* 如果我删除了 toString() 它会给我错误 参数类型“新闻”不能分配给参数类型 '细绳'。 */
这是因为Text
小部件希望他的输入是String
类型而不是News
类型。
【讨论】:
我将保留FutureBuilder
原样并完全删除对news
的任何引用。除非您需要实际操纵未来本身,否则您几乎不需要将其与使用和解包的地方分开存储。以上是关于在 Flutter 中从 API 获取数据的主要内容,如果未能解决你的问题,请参考以下文章