为什么我无法通过 Json 在我的 Flutter 应用程序上获取数据
Why I can't fetch data by Json on my Flutter App
我没有从假 Api 获得任何数据:https://jsonplaceholder.typicode.com/users to my flutter App. Can anyone please give me piece of advise why or how I can get those data on my app. For creating the Model file using https://app.quicktype.io/.
Json模型文件:
import 'dart:convert';
List<JsonModel> jsonModelFromJson(String str) =>
List<JsonModel>.from(json.decode(str).map((x) => JsonModel.fromJson(x)));
String jsonModelToJson(List<JsonModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class JsonModel {
JsonModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
int? id;
String? name;
String? username;
String? email;
Address? address;
String? phone;
String? website;
Company? company;
factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address?.toJson(),
"phone": phone,
"website": website,
"company": company?.toJson(),
};
}
class Address {
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
String? street;
String? suite;
String? city;
String? zipcode;
Geo? geo;
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo?.toJson(),
};
}
class Geo {
Geo({
this.lat,
this.lng,
});
String? lat;
String? lng;
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
Company({
this.name,
this.catchPhrase,
this.bs,
});
String? name;
String? catchPhrase;
String? bs;
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
服务或JsonApi文件:
import 'dart:convert';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
class JsonApi {
bool loading = true;
var json_Data;
Future<JsonModel> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
var jsonModel = null;
try {
if (response.statusCode == 200) {
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
print(jsonModel);
} else {
throw Exception("falied to load");
}
} catch (Exception) {
return jsonModel;
}
return jsonModel;
}
}
尝试调用但是进度条没有关闭说明我没有得到数据
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:flutter_learning_from_pageview/Service/JsonApi.dart';
class JsonData extends StatefulWidget {
const JsonData({Key? key}) : super(key: key);
@override
_JsonDataState createState() => _JsonDataState();
}
class _JsonDataState extends State<JsonData> {
bool loading = true;
Future<JsonModel>? _jsonModel;
@override
void initState() {
_jsonModel = JsonApi().getJsonData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _jsonModel,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(""),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}
从初始状态你必须这样改变:
@override
void initState() {
callApi();
super.initState();
}
void callApi() async {
_jsonModel = await JsonApi().getJsonData();
}
因为你没有用 await 调用它,所以它没有数据
我发现了你的问题。您试图在错误的 jsonModel
.
中获取数据
删除此代码
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
改用这个
jsonModel = jsonModelFromJson(response.body);
您的 Api 数据采用 Array
格式,您正尝试以 Class 格式存储。
你犯了一些错误所以试着把它改成这样。您正在尝试仅使用一个元素来解析数据列表。
class JsonApi {
Future<List<JsonModel>> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
if (response.statusCode == 200) {
return jsonModelFromJson(response.body);
} else {
throw Exception("falied to load");
}
}
}
然后试试这个代码
late final Future<List<JsonModel>> _futureData;
apiCalling() {
_futureData = JsonApi().getJsonData();
}
@override
void initState() {
apiCalling();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot<List<JsonModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () {
setState(() {});
},
title: Text(snapshot.data![index].name!),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
确保 response.body 正在返回数据。
避免使用 ?在 futures 中,否则当 body 为 null 时快照可能一直为空。 ui 将始终显示正在加载。
为了使您的代码看起来更简单:
内部有状态小部件:
late final Future<List<Data>> _futureData;
并且在您的 initState 中:
@override
void initState(){
_futureData = provider.loadFutureData();
super.initState();
}
或者如果您不使用提供商:
@override
void initState(){
_futureData = loadDataFromFunction();
super.initState();
}
试试下面的代码希望对你有帮助。
Your API Call:
Future<List<dynamic>> getJobsData() async {
String url = 'https://jsonplaceholder.typicode.com/users';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body);
}
Your Widget:
Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
shrinkWrap: true,
physics:const NeverScrollableScrollPhysics(),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var id = snapshot.data![index]['id'];
var name = snapshot.data![index]['name'];
var username = snapshot.data![index]['username'];
var email = snapshot.data![index]['email'];
var phone = snapshot.data![index]['phone'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(id.toString()),
title: Text(name),
subtitle: Text(
username + '\n' + email + '\n' + phone.toString(),
),
),
);
},
),
);
}
return const CircularProgressIndicator();
},
),
),
参考我的回答 and 从 json API
获取数据
您的结果屏幕->
我没有从假 Api 获得任何数据:https://jsonplaceholder.typicode.com/users to my flutter App. Can anyone please give me piece of advise why or how I can get those data on my app. For creating the Model file using https://app.quicktype.io/.
Json模型文件:
import 'dart:convert';
List<JsonModel> jsonModelFromJson(String str) =>
List<JsonModel>.from(json.decode(str).map((x) => JsonModel.fromJson(x)));
String jsonModelToJson(List<JsonModel> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class JsonModel {
JsonModel({
this.id,
this.name,
this.username,
this.email,
this.address,
this.phone,
this.website,
this.company,
});
int? id;
String? name;
String? username;
String? email;
Address? address;
String? phone;
String? website;
Company? company;
factory JsonModel.fromJson(Map<String, dynamic> json) => JsonModel(
id: json["id"],
name: json["name"],
username: json["username"],
email: json["email"],
address: Address.fromJson(json["address"]),
phone: json["phone"],
website: json["website"],
company: Company.fromJson(json["company"]),
);
Map<String, dynamic> toJson() => {
"id": id,
"name": name,
"username": username,
"email": email,
"address": address?.toJson(),
"phone": phone,
"website": website,
"company": company?.toJson(),
};
}
class Address {
Address({
this.street,
this.suite,
this.city,
this.zipcode,
this.geo,
});
String? street;
String? suite;
String? city;
String? zipcode;
Geo? geo;
factory Address.fromJson(Map<String, dynamic> json) => Address(
street: json["street"],
suite: json["suite"],
city: json["city"],
zipcode: json["zipcode"],
geo: Geo.fromJson(json["geo"]),
);
Map<String, dynamic> toJson() => {
"street": street,
"suite": suite,
"city": city,
"zipcode": zipcode,
"geo": geo?.toJson(),
};
}
class Geo {
Geo({
this.lat,
this.lng,
});
String? lat;
String? lng;
factory Geo.fromJson(Map<String, dynamic> json) => Geo(
lat: json["lat"],
lng: json["lng"],
);
Map<String, dynamic> toJson() => {
"lat": lat,
"lng": lng,
};
}
class Company {
Company({
this.name,
this.catchPhrase,
this.bs,
});
String? name;
String? catchPhrase;
String? bs;
factory Company.fromJson(Map<String, dynamic> json) => Company(
name: json["name"],
catchPhrase: json["catchPhrase"],
bs: json["bs"],
);
Map<String, dynamic> toJson() => {
"name": name,
"catchPhrase": catchPhrase,
"bs": bs,
};
}
服务或JsonApi文件:
import 'dart:convert';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http;
class JsonApi {
bool loading = true;
var json_Data;
Future<JsonModel> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
var jsonModel = null;
try {
if (response.statusCode == 200) {
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
print(jsonModel);
} else {
throw Exception("falied to load");
}
} catch (Exception) {
return jsonModel;
}
return jsonModel;
}
}
尝试调用但是进度条没有关闭说明我没有得到数据
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_learning_from_pageview/Model/JsonModel.dart';
import 'package:flutter_learning_from_pageview/Service/JsonApi.dart';
class JsonData extends StatefulWidget {
const JsonData({Key? key}) : super(key: key);
@override
_JsonDataState createState() => _JsonDataState();
}
class _JsonDataState extends State<JsonData> {
bool loading = true;
Future<JsonModel>? _jsonModel;
@override
void initState() {
_jsonModel = JsonApi().getJsonData();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _jsonModel,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(""),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
}
从初始状态你必须这样改变:
@override
void initState() {
callApi();
super.initState();
}
void callApi() async {
_jsonModel = await JsonApi().getJsonData();
}
因为你没有用 await 调用它,所以它没有数据
我发现了你的问题。您试图在错误的 jsonModel
.
删除此代码
var decode = json.decode(response.body);
jsonModel = JsonModel.fromJson(decode);
改用这个
jsonModel = jsonModelFromJson(response.body);
您的 Api 数据采用 Array
格式,您正尝试以 Class 格式存储。
你犯了一些错误所以试着把它改成这样。您正在尝试仅使用一个元素来解析数据列表。
class JsonApi {
Future<List<JsonModel>> getJsonData() async {
var client = http.Client();
String uri = "https://jsonplaceholder.typicode.com/users";
var response = await client.get(Uri.parse(uri));
if (response.statusCode == 200) {
return jsonModelFromJson(response.body);
} else {
throw Exception("falied to load");
}
}
}
然后试试这个代码
late final Future<List<JsonModel>> _futureData;
apiCalling() {
_futureData = JsonApi().getJsonData();
}
@override
void initState() {
apiCalling();
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _futureData,
builder: (context, AsyncSnapshot<List<JsonModel>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
//itemCount: json_Data == null ? 0 : json_Data.length,
itemBuilder: (context, index) {
return ListTile(
onTap: () {
setState(() {});
},
title: Text(snapshot.data![index].name!),
//subtitle: Text(json_Data[index]["body"]),
);
});
} else {
return Center(child: CircularProgressIndicator());
}
},
),
),
);
}
确保 response.body 正在返回数据。
避免使用 ?在 futures 中,否则当 body 为 null 时快照可能一直为空。 ui 将始终显示正在加载。
为了使您的代码看起来更简单:
内部有状态小部件:
late final Future<List<Data>> _futureData;
并且在您的 initState 中:
@override
void initState(){
_futureData = provider.loadFutureData();
super.initState();
}
或者如果您不使用提供商:
@override
void initState(){
_futureData = loadDataFromFunction();
super.initState();
}
试试下面的代码希望对你有帮助。
Your API Call:
Future<List<dynamic>> getJobsData() async {
String url = 'https://jsonplaceholder.typicode.com/users';
var response = await http.get(Uri.parse(url), headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
});
return json.decode(response.body);
}
Your Widget:
Center(
child: FutureBuilder<List<dynamic>>(
future: getJobsData(),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: ListView.builder(
shrinkWrap: true,
physics:const NeverScrollableScrollPhysics(),
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
var id = snapshot.data![index]['id'];
var name = snapshot.data![index]['name'];
var username = snapshot.data![index]['username'];
var email = snapshot.data![index]['email'];
var phone = snapshot.data![index]['phone'];
return Card(
shape: RoundedRectangleBorder(
side: BorderSide(
color: Colors.green.shade300,
),
borderRadius: BorderRadius.circular(15.0),
),
child: ListTile(
leading: Text(id.toString()),
title: Text(name),
subtitle: Text(
username + '\n' + email + '\n' + phone.toString(),
),
),
);
},
),
);
}
return const CircularProgressIndicator();
},
),
),
参考我的回答
您的结果屏幕->