gpt4 book ai didi

json - Flutter如何JSON序列化数据表单api

转载 作者:IT王子 更新时间:2023-10-29 07:08:52 28 4
gpt4 key购买 nike

我正在尝试在我的 flutter 应用程序中使用模型来让这个概念在我的应用程序中启动并运行。我对 OOP 很陌生,所以我想尽可能多地学习。我的问题是我有来自 OpenWeather API 的 API 响应,我的方法是调用 api 获取数据。效果很好,我通常使用 JSON 手动解码和访问 propetires。但我想要的是按模型分解/预处理我的 JSON。下面的代码运行良好,但我想应用使用 JSON 序列化的概念,但我不知道如何开始。我所有的尝试都失败了...:/

我用 https://app.quicktype.io/ 生成了模型在家伙的帮助下形成了我之前的答案。

型号:

import 'dart:convert';

Forcast forcastFromJson(String str) => Forcast.fromJson(json.decode(str));

String forcastToJson(Forcast data) => json.encode(data.toJson());

class Forcast {
String cod;
double message;
int cnt;
List<ListElement> list;
City city;

Forcast({
this.cod,
this.message,
this.cnt,
this.list,
this.city,
});

factory Forcast.fromJson(Map<String, dynamic> json) => new Forcast(
cod: json["cod"],
message: json["message"].toDouble(),
cnt: json["cnt"],
list: new List<ListElement>.from(
json["list"].map((x) => ListElement.fromJson(x))),
city: City.fromJson(json["city"]),
);

Map<String, dynamic> toJson() => {
"cod": cod,
"message": message,
"cnt": cnt,
"list": new List<dynamic>.from(list.map((x) => x.toJson())),
"city": city.toJson(),
};
}

class City {
int id;
String name;
Coord coord;
String country;

City({
this.id,
this.name,
this.coord,
this.country,
});

factory City.fromJson(Map<String, dynamic> json) => new City(
id: json["id"],
name: json["name"],
coord: Coord.fromJson(json["coord"]),
country: json["country"],
);

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

class Coord {
double lat;
double lon;

Coord({
this.lat,
this.lon,
});

factory Coord.fromJson(Map<String, dynamic> json) => new Coord(
lat: json["lat"].toDouble(),
lon: json["lon"].toDouble(),
);

Map<String, dynamic> toJson() => {
"lat": lat,
"lon": lon,
};
}

class ListElement {
int dt;
MainClass main;
List<Weather> weather;
Clouds clouds;
Wind wind;
Sys sys;
DateTime dtTxt;
Rain rain;
Rain snow;

ListElement({
this.dt,
this.main,
this.weather,
this.clouds,
this.wind,
this.sys,
this.dtTxt,
this.rain,
this.snow,
});

factory ListElement.fromJson(Map<String, dynamic> json) => new ListElement(
dt: json["dt"],
main: MainClass.fromJson(json["main"]),
weather: new List<Weather>.from(
json["weather"].map((x) => Weather.fromJson(x))),
clouds: Clouds.fromJson(json["clouds"]),
wind: Wind.fromJson(json["wind"]),
sys: Sys.fromJson(json["sys"]),
dtTxt: DateTime.parse(json["dt_txt"]),
rain: json["rain"] == null ? null : Rain.fromJson(json["rain"]),
snow: json["snow"] == null ? null : Rain.fromJson(json["snow"]),
);

Map<String, dynamic> toJson() => {
"dt": dt,
"main": main.toJson(),
"weather": new List<dynamic>.from(weather.map((x) => x.toJson())),
"clouds": clouds.toJson(),
"wind": wind.toJson(),
"sys": sys.toJson(),
"dt_txt": dtTxt.toIso8601String(),
"rain": rain == null ? null : rain.toJson(),
"snow": snow == null ? null : snow.toJson(),
};
}

class Clouds {
int all;

Clouds({
this.all,
});

factory Clouds.fromJson(Map<String, dynamic> json) => new Clouds(
all: json["all"],
);

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

class MainClass {
double temp;
double tempMin;
double tempMax;
double pressure;
double seaLevel;
double grndLevel;
int humidity;
double tempKf;

MainClass({
this.temp,
this.tempMin,
this.tempMax,
this.pressure,
this.seaLevel,
this.grndLevel,
this.humidity,
this.tempKf,
});

factory MainClass.fromJson(Map<String, dynamic> json) => new MainClass(
temp: json["temp"].toDouble(),
tempMin: json["temp_min"].toDouble(),
tempMax: json["temp_max"].toDouble(),
pressure: json["pressure"].toDouble(),
seaLevel: json["sea_level"].toDouble(),
grndLevel: json["grnd_level"].toDouble(),
humidity: json["humidity"],
tempKf: json["temp_kf"].toDouble(),
);

Map<String, dynamic> toJson() => {
"temp": temp,
"temp_min": tempMin,
"temp_max": tempMax,
"pressure": pressure,
"sea_level": seaLevel,
"grnd_level": grndLevel,
"humidity": humidity,
"temp_kf": tempKf,
};
}

class Rain {
double the3H;

Rain({
this.the3H,
});

factory Rain.fromJson(Map<String, dynamic> json) => new Rain(
the3H: json["3h"] == null ? null : json["3h"].toDouble(),
);

Map<String, dynamic> toJson() => {
"3h": the3H == null ? null : the3H,
};
}

class Sys {
Pod pod;

Sys({
this.pod,
});

factory Sys.fromJson(Map<String, dynamic> json) => new Sys(
pod: podValues.map[json["pod"]],
);

Map<String, dynamic> toJson() => {
"pod": podValues.reverse[pod],
};
}

enum Pod { D, N }

final podValues = new EnumValues({"d": Pod.D, "n": Pod.N});

class Weather {
int id;
MainEnum main;
Description description;
String icon;

Weather({
this.id,
this.main,
this.description,
this.icon,
});

factory Weather.fromJson(Map<String, dynamic> json) => new Weather(
id: json["id"],
main: mainEnumValues.map[json["main"]],
description: descriptionValues.map[json["description"]],
icon: json["icon"],
);

Map<String, dynamic> toJson() => {
"id": id,
"main": mainEnumValues.reverse[main],
"description": descriptionValues.reverse[description],
"icon": icon,
};
}

enum Description {
CLEAR_SKY,
BROKEN_CLOUDS,
LIGHT_RAIN,
MODERATE_RAIN,
FEW_CLOUDS
}

final descriptionValues = new EnumValues({
"broken clouds": Description.BROKEN_CLOUDS,
"clear sky": Description.CLEAR_SKY,
"few clouds": Description.FEW_CLOUDS,
"light rain": Description.LIGHT_RAIN,
"moderate rain": Description.MODERATE_RAIN
});

enum MainEnum { CLEAR, CLOUDS, RAIN }

final mainEnumValues = new EnumValues({
"Clear": MainEnum.CLEAR,
"Clouds": MainEnum.CLOUDS,
"Rain": MainEnum.RAIN
});

class Wind {
double speed;
double deg;

Wind({
this.speed,
this.deg,
});

factory Wind.fromJson(Map<String, dynamic> json) => new Wind(
speed: json["speed"].toDouble(),
deg: json["deg"].toDouble(),
);

Map<String, dynamic> toJson() => {
"speed": speed,
"deg": deg,
};
}

class EnumValues<T> {
Map<String, T> map;
Map<T, String> reverseMap;

EnumValues(this.map);

Map<T, String> get reverse {
if (reverseMap == null) {
reverseMap = map.map((k, v) => new MapEntry(v, k));
}
return reverseMap;
}
}

进行API调用的网络:

import 'package:http/http.dart' as http;
import 'dart:convert';

class NetworkHelper {
NetworkHelper({this.text});

String text;
String apiKey = '';

Future<dynamic> getData(text) async {
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?q=$text&appid=$apiKey&units=metric');

if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);

return decodedData;
} else {
print(response.statusCode);
}
}

Future<dynamic> getForcast(text) async {
http.Response response = await http.get(
'http://api.openweathermap.org/data/2.5/forecast?q=${text}&units=metric&appid=$apiKey');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);

return decodedData;
} else {
print(response.statusCode);
}
}

Future<dynamic> getDataLocation(lat, lon) async {
http.Response response = await http.get(
'https://api.openweathermap.org/data/2.5/weather?lat=$lat&lon=$lon&appid=$apiKey&units=metric');

if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);

return decodedData;
} else {
print(response.statusCode);
}
}

Future<dynamic> getForcastLocation(lat, lon) async {
http.Response response = await http.get(
'http://api.openweathermap.org/data/2.5/forecast?lat=$lat&lon=$lon&units=metric&appid=$apiKey');
if (response.statusCode == 200) {
var decodedData = jsonDecode(response.body);

return decodedData;
} else {
print(response.statusCode);
}
}
}

我显示数据的天气:

import 'package:flutter/material.dart';
import 'package:weather/common/format.dart';

import 'package:weather/service/Network.dart';
import 'package:weather/service/location.dart';

class Weather extends StatefulWidget {
Weather({this.text});
final String text;

_WeatherState createState() => _WeatherState();
}

class _WeatherState extends State<Weather> {
NetworkHelper networkHelper = NetworkHelper();
Location location = Location();
Formats formats = Formats();
int temperature;
String cityName;
String description;
bool isLoading = true;
dynamic newData;
String city;
@override
void initState() {
super.initState();
city = widget.text;
buildUI(city);
}

buildUI(String text) async {
var weatherData = await networkHelper.getData(text);
var forecastData = await networkHelper.getForcast(text);
double temp = weatherData['main']['temp'];
temperature = temp.toInt();
cityName = weatherData['name'];
description = weatherData['weather'][0]['description'];
newData = forecastData['list'].toList();
setState(() {
isLoading = false;
});
}

buildUIByLocation() async {
await location.getCurrentLocation();
var weatherLocation = await networkHelper.getDataLocation(
location.latitude, location.longitude);
var forcastLocation = await networkHelper.getForcastLocation(
location.latitude, location.longitude);
double temp = weatherLocation['main']['temp'];
temperature = temp.toInt();
cityName = weatherLocation['name'];
description = weatherLocation['weather'][0]['description'];
newData = forcastLocation['list'].toList();
setState(() {
isLoading = false;
});
}

Widget get _pageToDisplay {
if (isLoading == true) {
return _loadingView;
} else {
return _weatherView;
}
}

Widget get _loadingView {
return Center(child: CircularProgressIndicator());
}

Widget get _weatherView {
return SafeArea(
child: Column(
children: <Widget>[
Flexible(
flex: 1,
child: Container(
margin: EdgeInsets.fromLTRB(12, 1, 30, 0),
decoration: new BoxDecoration(
color: Color(0xff4556FE),
borderRadius: BorderRadius.all(Radius.circular(10.0)),
boxShadow: [
BoxShadow(
color: Color(0xFFD4DAF6),
offset: Offset(20, 20),
),
BoxShadow(
color: Color(0xFFadb6ff),
offset: Offset(10, 10),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'$cityName',
style: TextStyle(fontSize: 25, color: Colors.white),
),
SizedBox(
height: 5,
),
Text(
'$temperature°C',
style: TextStyle(fontSize: 50, color: Colors.white),
),
],
),
),
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'$description',
style: TextStyle(fontSize: 25, color: Colors.white),
),
],
),
)
],
),
),
),
SizedBox(
height: 30,
),
Flexible(
flex: 2,
child: Container(
margin: EdgeInsets.fromLTRB(12, 10, 12, 0),
decoration: new BoxDecoration(
color: Color(0xff4556FE),
borderRadius: BorderRadius.vertical(top: Radius.circular(10.0)),
),
child: ListView.builder(
padding: const EdgeInsets.all(8.0),
itemCount: newData.length,
itemBuilder: (BuildContext context, int index) {
return Container(
margin: const EdgeInsets.all(4.0),
height: 50,
child: Center(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
formats.readTimeStamp(newData[index]['dt']),
style: TextStyle(
color: Colors.white, fontSize: 14),
),
Text(
newData[index]['weather'][0]['main'].toString(),
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.w600),
),
Text(
formats.floatin(newData[index]['main']['temp']),
style: TextStyle(
color: Colors.white,
fontSize: 16,
fontWeight: FontWeight.w600),
),
],
),
));
}),
),
),
],
),
);
}

Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: <Widget>[
IconButton(
padding: EdgeInsets.fromLTRB(0, 0, 20, 0),
icon: Icon(Icons.autorenew, color: Colors.black, size: 30),
onPressed: () {
if (city == "") {
setState(() {
isLoading = true;
buildUIByLocation();
});
} else {
setState(() {
isLoading = true;
buildUI(city);
});
}
},
),
IconButton(
padding: EdgeInsets.fromLTRB(0, 0, 15, 0),
icon: Icon(
Icons.location_on,
color: Colors.black,
size: 30,
),
onPressed: () async {
setState(() {
city = '';
isLoading = true;
});
await buildUIByLocation();
},
)
],
leading: IconButton(
icon: Icon(Icons.arrow_back_ios, color: Colors.black),
onPressed: () {
Navigator.pop(context);
},
),
elevation: 0,
backgroundColor: Colors.transparent,
title: const Text(
'Change location',
style: TextStyle(color: Colors.black),
),
),
body: Stack(
children: <Widget>[
Container(
decoration: BoxDecoration(color: Color(0xFFfafafa)),
child: Padding(
padding: const EdgeInsets.fromLTRB(5, 20, 5, 0),
child: Center(child: _pageToDisplay),
),
)
],
),
);
}
}

最佳答案

这是一个非常基本的例子。在这里您可以看到 Car 模型类及其基本属性。数据将由 CarRepository 类获取,此类执行网络操作并将数据从 json 映射到模型。CarScreen 类是一个有状态的小部件,并在 initState 之后调用 CarRepository。如果从网络获取数据,汽车将显示在列表中。获取时会显示加载指示器。

import 'dart:convert';
import 'package:http/http.dart' as http;

class Car {
//
// Attributes
//
int id;
String name;
String color;
int speed;

//
// Constructor
//
Car({
@required this.id,
@required this.name,
@required this.color,
@required this.speed,
});

// convert Json to an car object object
factory Car.fromJson(Map<String, dynamic> json) {
return Car(
id: json['id'] as int,
name: json['name'] as String,
color: json['color'] as String,
speed: json['speed'] as int,
);
}
}

class CarRepository {
/// Load all cars form api and will convert it
/// to an list of cars.
///
/// {
/// "results": [
/// {
/// "id": 1,
/// "name": "Tesla Model 3",
/// "color": "red",
/// "speed": 225
/// },
/// {
/// "id": 3,
/// "name": "Tesla Model S",
/// "color": "black",
/// "speed": 255
/// }
/// ]
/// }
///
///
static Future<List<Car>> fetchAll() async {
String query = '';
String url = Uri.encodeFull("https://xxx.de/api/cars" + query);
final response = await http.get(url);

if (response.statusCode == 200) {
Map data = json.decode(response.body);
final cars = (data['results'] as List).map((i) => new Car.fromJson(i));
return cars.toList();
} else {
return [];
}
}
}

class CarsScreen extends StatefulWidget {
_CarsScreenState createState() => _CarsScreenState();
}

class _CarsScreenState extends State<CarsScreen> {
bool _isLoading = true;
List<Car> _cars = [];

@override
void initState() {
super.initState();
fetchCars();
}

Future fetchCars() async {
_cars = await CarRepository.fetchAll();
setState(() {
_isLoading = false;
});
}

@override
Widget build(BuildContext context) {
if (_isLoading) {
return Scaffold(
appBar: AppBar(
title: Text('Cars'),
),
body: Container(
child: Center(
child: CircularProgressIndicator(),
),
),
);
} else {
return Scaffold(
appBar: AppBar(
title: Text('Cars'),
),
body: ListView.builder(
itemCount: _cars.length,
itemBuilder: (context, index) {
Car car = _cars[index];
return ListTile(
title: Text(car.name),
subtitle: Text(car.color),
);
},
),
);
}
}
}

关于json - Flutter如何JSON序列化数据表单api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57656703/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com