iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
1
Mobile Development

新手試試用Flutter做Netflix UI系列 第 27

[Day27]Flutter Netflix UI 使用json_serializable轉換Model

  • 分享至 

  • xImage
  •  

大家好,今天要來做Model的轉換,使用到json_serializable、build_runner

這是前面定義的User,包含name跟assetName,想為它添加Json序列化的方法可以自己定義,但自己定義有時候項目多了,就有些繁瑣,今天要來用json_serializable幫助我們做這個步驟

//位於user.dart中
class User {
  User(this.name, this.assetName);

  String name;
  String assetName;
}

在pubspec.yaml下新增 json_serializable: ^3.5.0,然後pub get

dependencies:
  json_serializable: ^3.5.0

user.dart

import json_annotation.dart進user.dart
在class上方加入@JsonSerializable()
新增part 'user.g.dart';在上方,這時這行會是紅色的,是因為我們還沒有user.g.dart這個檔案

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
  User(this.name, this.assetName);

  String name;
  String assetName;
}

生成user.g.dart

接著我們再到pubspec.yaml,新增build_runner:在dev_dependencies下,然後pub get

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:

接著在Terminal中輸入,執行後會開始自動幫助建檔案

flutter packages pub run build_runner build

完成時就會發現原本資料夾裡面多了一個user.g.dart,這邊它根據原本的class去自動做出兩個方法
UserFromJson與UserToJson

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) {
  return User(
    json['name'] as String,
    json['assets_name'] as String,
  );
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
      'name': instance.name,
      'assets_name': instance.assetName,
    };

我們在原本的user.dart中加入這兩行,就可以使用User.fromJson以及toJson()

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);

名稱不一樣的時候

假如傳進來的key是assets_name與程式裡面變數名稱是assetsName,也有操作可以轉換,加上@JsonKey(name: 'assets_name'),再重新生成一次就可以

class User {
  User(this.name, this.assetName);

  String name;
  @JsonKey(name: 'assets_name')
  String assetName;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);

  Map<String, dynamic> toJson() => _$UserToJson(this);
}

測試

假設一個json資料

 String jsonUserData =
      "{\"users\":[{\"name\":\"p1\",\"assets_name\":\"assets\/icons\/icon_user.jpg\"},{\"name\":\"p1\",\"assets_name\":\"assets\/icons\/icon_user.jpg\"},{\"name\":\"p1\",\"assets_name\":\"assets\/icons\/icon_user.jpg\"},{\"name\":\"p1\",\"assets_name\":\"assets\/icons\/icon_user.jpg\"},{\"name\":\"p1\",\"assets_name\":\"assets\/icons\/icon_user.jpg\"}]}";

使用json.decode()可以把json字串轉回Map<String,dynamic>
data['users']如上定義是一個List,使用User.fromJson(element)將每一個element資料解析成User

List<User> _users =[];
 Map data = json.decode(jsonUserData);
    (data['users'] as List).forEach((element轉成User) {
      _users.add(User.fromJson(element));
    });

flutter_gen/pubspec.yaml Not Found問題

flutter_gen/pubspec.yaml Not Found問題
今天使用的時候發生這個問題,主要原因是前面做國際化的時候使用過自動生成code,l10n.yaml,這兩個好像有點衝突

flutter:
  generate: true

所以根據其中一則回覆,我們到
flutter_neflix_cover/.dart_tool/flutter_gen/
新建一個pubspec.yaml,內容如下,就可以暫時解決這個問題

name: test
description: A new Flutter application.
version: 1.0.0

dependencies:

dev_dependencies:

資料來源
flutter 教學 教程基礎篇 (27) 自動產生 JSON Serialize,Auto JSON serialize

GitHub連結: flutter-netflix-clone


上一篇
[Day26]Flutter Netflix UI ListView中第一個可見的Item顯示,其他都變暗
下一篇
[Day28]初探Firebase Cloud Messaging for Flutter
系列文
新手試試用Flutter做Netflix UI30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言