问题描述
我已经能够遵循Flutter上有关基本UI设计的一些教程,并且是API调用的新手。我认为我需要在进行API调用后转换类型,但是我不知道如何。
注意:我知道一个文件中有很多代码,但是我会将API调用文件和自定义类文件与我的主文件分开
import 'dart:async';
import 'dart:convert';
import 'package:Flutter/foundation.dart';
import 'package:Flutter/material.dart';
import 'package:http/http.dart' as http;
Future<Country> fetchAlbum() async {
final response = await http.get('https://restcountries.eu/rest/v2/all');
if (response.statusCode == 200) {
// If the server did return a 200 OK response,// then parse the JSON.
return Country.fromJson(json.decode(response.body));
} else {
// If the server did not return a 200 OK response,// then throw an exception.
throw Exception('Failed to load album');
}
}
class Country {
final String name;
final List<String> topLevelDomain;
final String alpha2Code;
final String alpha3Code;
final String callingCodes;
final String capital;
final String region;
final String subregion;
final int population;
final List<int> latlng;
final String demonym;
final int area;
final int gini;
final List<String> timezones;
final List<String> borders;
final String nativeName;
final int numericCode;
final List<String> currencies;
final List<String> translations;
final String flag;
final String cioc;
Country({
@required this.name,@required this.topLevelDomain,@required this.alpha2Code,@required this.alpha3Code,@required this.callingCodes,@required this.capital,@required this.region,@required this.subregion,@required this.population,@required this.latlng,@required this.demonym,@required this.area,@required this.gini,@required this.timezones,@required this.borders,@required this.nativeName,@required this.numericCode,@required this.currencies,@required this.translations,@required this.flag,@required this.cioc,});
factory Country.fromJson(Map<String,dynamic> json) {
return Country(
name: json['name'],topLevelDomain: json['topLevelDomain'],alpha2Code: json['alpha2Code'],alpha3Code: json['alpha3Code'],callingCodes: json['callingCodes'],capital: json['capital'],region: json['region'],subregion: json['subregion'],population: json['population'],latlng: json['latlng'],demonym: json['demonym'],area: json['area'],gini: json['gini'],timezones: json['timezones'],borders: json['borders'],nativeName: json['nativeName'],numericCode: json['numericCode'],currencies: json['currencies'],translations: json['translations'],flag: json['flag'],cioc: json['cioc'],);
}
}
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<Country> futureAlbum;
@override
void initState() {
super.initState();
futureAlbum = fetchAlbum();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Fetch Data Example',theme: ThemeData(
primarySwatch: Colors.blue,),home: Scaffold(
appBar: AppBar(
title: Text('Fetch Data Example'),body: Center(
child: FutureBuilder<Country>(
future: futureAlbum,builder: (context,snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.name);
} else if (snapshot.hasError) {
return Text("${snapshot.error}");
}
// By default,show a loading spinner.
return CircularProgressIndicator();
},);
}
}
这是我的模拟器屏幕的样子:http://i1.imgrr.com/18Z/7512_Screenshot1599026660.png
解决方法
第12行“返回Country.fromJson(json.decode(response.body));'
我认为“ json.decode(response.body)”的类型是“列表”,但此处的参数类型是Map。也许您的响应是一个Country对象列表,但它返回了1个Country对象。这就是为什么出现此错误
,您的API返回List
而不是Map
。
您需要将每个元素映射为Country
。
Future<List<Country>> fetchAlbum() async {
final response = await http.get('https://restcountries.eu/rest/v2/all');
if (response.statusCode == 200) {
List<Country> countryList = ((json.decode(response.body) as List).map((i) => Country.fromJson(i)).toList();
return countryList;
} else {
throw Exception('Failed to load album');
}
}