flutter 动画json_Flutter 中的 JSON 解析

JSON 是我们开发中最常使用的一种数据格式,这篇文章中,我们主要看看在开发中最常见的几种格式的 JSON 数据在 Flutter 中的解析:

以下案例中,我们都会将json文件放到本地,也就是 assets 文件中,然后从本地读取这些文件进行解析。

如我们需要读取 assets/person.json :

image

那么就需要在 pubspec.yaml 中做如下配置:

flutter:

uses-material-design: true

# 资源文件配置

assets:

- assets/person.json

下面我们就来解析一些常见的 Json 格式的数据。

如果对 Dart 基础还不是很了解,可以先看看这篇文章 Dart 基础入门

简单的对象解析

定义一个 person.json 如下:

{

"name": "jack",

"age": 18,

"height": 175.0

}

和在 Java 里面一样,我们首先需要构建一个 Person 的实体类,如下:

class Person {

String name;

int age;

double height;

Person({this.name, this.age, this.height});

factory Person.fromJson(Map json) {

return Person(name: json['name'], age: json['age'], height: json['height']);

}

}

接着,我们在创建一个 person_service.dart 来解析 person.json。

该类中需要导入如下几个依赖库:

// 使用该库中的 rootBundle 对象来读取 perosn.json 文件

import 'package:flutter/services.dart';

// json

import 'dart:convert';

// 异步 Future

import 'dart:async';

person_service.dart

import 'package:flutter/services.dart';

import 'dart:convert';

import 'dart:async';

import '../models/person.dart';

// 读取 assets 文件夹中的 person.json 文件

Future _loadPersonJson() async {

return await rootBundle.loadString('assets/person.json');

}

// 将 json 字符串解析为 Person 对象

Future decodePerson() async {

// 获取本地的 json 字符串

String personJson = await _loadPersonJson();

// 解析 json 字符串,返回的是 Map 类型

final jsonMap = json.decode(personJson);

print('jsonMap runType is ${jsonMap.runtimeType}');

Person person = Person.fromJson(jsonMap);

print(

'person name is ${person.name}, age is ${person.age}, height is ${person.height}');

return person;

}

输入如下:

flutter: jsonMap runType is _InternalLinkedHashMap

flutter: person name is jack, age is 18, height is 175.0

可以看出 json.decode(personJson) 方法返回的类型为 _InternalLinkedHashMap ,意思就是这个 Map 的 key 为 String 类型,而 value 的类型为 dynamic 的,也就是动态的,就如 person.json 中,key 都是 String 类型的,但是 value 可能是 String 、int、double 等等类型。

包含数组的对象

定义一个 country.json 如下:

{

"name": "China",

"cities": [

"Beijing",

"Shanghai"

]

}

实体类如下:

class Country {

String name;

List cities;

Country({this.name, this.cities});

factory Country.fromJson(Map json) {

return Country(name: json['name'], cities: json['cities']);

}

}

Service 类如下:

import 'dart:async';

import 'package:flutter/services.dart';

import 'dart:convert';

import '../models/country.dart';

Future _loadCountryJson() async {

return await rootBundle.loadString('assets/country.json');

}

Future decodeCountry() async {

String countryJson = await _loadCountryJson();

Map jsonMap = json.decode(countryJson);

Country country = Country.fromJson(jsonMap);

print('country name is ${country.name}');

return country;

}

然后我们在 main() 中去调用 decodeCountry() 运行,报错了...

Unhandled Exception: type 'List' is not a subtype of type 'List'

...

错误日志说 List 不是 List 的子类型,也就是我们在country的实体类中直接给 cities 属性赋值为 cities: json['cities'],我们先来看看 json['cities'] 是什么类型:

factory Country.fromJson(Map json) {

print('json["cities"] type is ${json['cities'].runtimeType}');

return Country(name: json['name'], cities: json['cities']);

}

输出如下:

flutter: json["cities"] type is List

这个时候我们需要将 Country.fromJson(...) 方法作如下更改:

factory Country.fromJson(Map json) {

print('json["cities"] type is ${json['cities'].runtimeType}');

var originList = json['cities'];

List cityList = new List.from(originList);

return Country(name: json['name'], cities: cityList);

}

上述代码中,我们创建了一个 List 类型的数组,然后将 List 数组中的元素都添加到了 List 中。输出如下:

flutter: json["cities"] type is List

flutter: country name is China

对象嵌套

定义一个 shape.json ,格式如下:

{

"name": "rectangle",

"property": {

"width": 5.0,

"height": 10.0

}

}

实体如下:

class Shape {

String name;

Property property;

Shape({this.name, this.property});

factory Shape.fromJson(Map json) {

return Shape(name: json['name'], property: json['property']);

}

}

class Property {

double width;

double height;

Property({this.width, this.height});

factory Property.fromJson(Map json) {

return Property(width: json['width'], height: json['height']);

}

}

Service 类如下:

import 'dart:async';

import 'dart:convert';

import 'package:flutter/services.dart';

import '../models/shape.dart';

Future _loadShapeJson() async {

return await rootBundle.loadString('assets/shape.json');

}

Future decodeShape() async {

String shapeJson = await _loadShapeJson();

Map jsonMap = json.decode(shapeJson);

Shape shape = Shape.fromJson(jsonMap);

print('shape name is ${shape.name}');

return shape;

}

运行之后,会报如下错误:

Unhandled Exception: type '_InternalLinkedHashMap' is not a subtype of type 'Property'

也就是说 property: json['property'] 这里赋值的类型是 _InternalLinkedHashMap 而不是 Property,json['property'] 的值是这样的 {width: 5.0, height: 10.0},它是一个 Map ,并不是一个 Property 对象,我们需要先将这个 Map 转化为对象,然后在赋值:

factory Shape.fromJson(Map json) {

print('json["property"] is ${json['property']}');

Property property = Property.fromJson(json['property']); // new line

return Shape(name: json['name'], property: property);

}

输出:

shape name is rectangle

复杂的对象数组嵌套

{

"id": "0302",

"class_name": "三年二班",

"students": [

{

"name": "叶湘伦",

"sex": "男"

},

{

"name": "路小雨",

"sex": "女"

}

]

}

实体:

class ClassInfo {

String id;

String name;

List studentList;

ClassInfo({this.id, this.name, this.studentList});

factory ClassInfo.fromJson(Map json) {

return ClassInfo(

id: json['id'],

name: json['class_name'],

studentList: json['students']);

}

}

class Student {

String name;

String sex;

Student({this.name, this.sex});

factory Student.fromJson(Map json) {

return Student(name: json['name'], sex: json['sex']);

}

}

service:

import 'dart:async';

import 'dart:convert';

import 'package:flutter/services.dart';

import '../models/class_info.dart';

Future _loadClassInfoJson() async {

return await rootBundle.loadString('assets/class_info.json');

}

Future decodeClassInfo() async {

String classInfoJson = await _loadClassInfoJson();

Map jsonMap = json.decode(classInfoJson);

ClassInfo classInfo = ClassInfo.fromJson(jsonMap);

classInfo.studentList

.forEach((student) => print('student name is ${student.name}'));

return classInfo;

}

上述代码在运行后还是会报错:

Unhandled Exception: type 'List' is not a subtype of type 'List'

同样,还是在 studentList: json['students'] 出问题了,我们把 json['students'] 的输出来看看:

[{name: 叶湘伦, sex: 男}, {name: 路小雨, sex: 女}]

上述结果的类型为 List 。现在我们需要将 List 转换到一个 List 类型的数组中,这里需要用到一个操作符 map,map 操作符的作用就是将某种类型转换为另一种类型。如下:

factory ClassInfo.fromJson(Map json) {

final originList = json['students'] as List;

List studentList =

originList.map((value) => Student.fromJson(value)).toList();

return ClassInfo(

id: json['id'], name: json['class_name'], studentList: studentList);

}

输出:

flutter: student name is 叶湘伦

flutter: student name is 路小雨

单纯的数组

member.json

[

{

"id": 1,

"name": "Jack"

},

{

"id": 2,

"name": "Rose"

},

{

"id": 3,

"name": "Karl"

}

]

实体:

class MemberList {

List memberList;

MemberList({this.memberList});

factory MemberList.fromJson(List listJson) {

List memberList =

listJson.map((value) => Member.fromJson(value)).toList();

return MemberList(memberList: memberList);

}

}

class Member {

int id;

String name;

Member({this.id, this.name});

factory Member.fromJson(Map json) {

return Member(id: json['id'], name: json['name']);

}

}

因为 member.json 是一个单纯的数组,所以上述代码中我们创建了一个 MemberList 类来将这个 Member 数组包含起来。

注意下上述代码中 MemberList.fromJson(...) 中的写法。

service:

import 'dart:async';

import 'package:flutter/services.dart';

import 'dart:convert';

import '../models/member.dart';

Future _loadMemberJson() async {

return await rootBundle.loadString('assets/member.json');

}

Future decodeMemberList() async {

String memberListJson = await _loadMemberJson();

List list = json.decode(memberListJson);

MemberList memberList = MemberList.fromJson(list);

memberList.memberList

.forEach((member) => print('member name is ${member.name}'));

return memberList;

}

输出:

flutter: member name is Jack

flutter: member name is Rose

flutter: member name is Karl

复杂的 Json 解析

之前的文章 Flutter 中 ListView 的使用 中用到了 豆瓣API ,这个 API 中返回的数据包含了当前热播的电影,大家尝试着按需解析一下吧 !!!

image

如有错误,还请指出。谢谢!!!

参考链接:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值