初投稿です。
Dart言語でJSONデータのHTTP通信を実装している際に、階層化された JSON に対しての処理を少し迷ったのでメモ代わりに書きます。
dart.json
{
"result":"Connection completed!",
"groupDistinct":["RADWIMPS","dustbox","Hi-STANDARD"],
"data":[
{"id":0,"name":"野田","part":"Gtvo","group":"RADWIMPS"},
{"id":1,"name":"桑原","part":"Gt","group":"RADWIMPS"},
{"id":2,"name":"武田","part":"Ba","group":"RADWIMPS"},
{"id":3,"name":"山口","part":"Dr","group":"RADWIMPS"},
{"id":4,"name":"SUGA","part":"GtVo","group":"dustbox"},
{"id":5,"name":"JOJI","part":"Ba","group":"dustbox"},
{"id":6,"name":"YU-KI","part":"Dr","group":"dustbox"},
{"id":7,"name":"難波","part":"Bavo","group":"Hi-STANDARD"},
{"id":8,"name":"恒岡","part":"Dr","group":"Hi-STANDARD"},
{"id":9,"name":"横山","part":"Gt","group":"Hi-STANDARD"}
]
}
というjsonデータに対して、dataの中身をmapで取得したかったというものです。
一度result,groudistinct,dataをそれぞれString型, List型, List型で取得した後、dataのみを連想配列で定義し直しました。
qitta.dart
//http通信で取得したjsonデータを格納するクラスの定義
class JsonList {
final String result;
final List groupDistinct;
final List data;
JsonList({this.result, this.groupDistinct, this.data});
factory JsonList.fromJson(Map<String, dynamic> json) {
return JsonList(
result: json['result'],
groupDistinct: json['groupDistinct'],
data: json['data']);
}
}
qitta.dart
//jsonで取得したlistをmapに定義しなおす処理
JsonList jsonList;
Map<String, dynamic> jsonDataMap;
List<Map> jsonDataMapList;
void _getData() async {
jsonList = await _getDataJsonList();
jsonDataMap = new Map<String, dynamic>.from(jsonList.data[0]);
jsonDataMapList = [jsonDataMap];
for (int i = 1; i < jsonList.data.length; i++) {
jsonDataMapList.add(new Map<String, dynamic>.from(jsonList.data[i]));
}
//取得後実行
setState(() {
this.jsonList = jsonList;
});
}
qitta.dart
//HTTP通信処理
Future<JsonList> _getDataJsonList() async {
String url;
url = "";//取得したいデータがあるurlを記述
final response = await http.get(url);
//final response = await http.post(url, body: {"event": event})
if (response.statusCode == 200) {
return JsonList.fromJson(json.decode(response.body));
} else {
// つながらなかった場合のエラー処理
}
}
もっといい書き方ありそう、、、
Dartとても便利な言語ですが、リファレンスできる情報がまだまだ少なく、自らまともなコードが書けない私は、最適なコードで書けているのかとても不安になります、、、。
もしこれを見た方で、「こうするといいよ!」という点があればコメントしていただけると嬉しいです。
おまけ
全体コードと実行結果のスクリーンショットです。
qitta.dart
import 'package:flutter/material.dart';
import 'dart:async'; //非同期処理用
import 'package:http/http.dart' as http;
import 'dart:convert'; //httpレスポンスをJSON形式に変換用
class API extends StatefulWidget {
@override
_APIState createState() => _APIState();
}
class JsonList {
final String result;
final List groupDistinct;
final List data;
JsonList({this.result, this.groupDistinct, this.data});
factory JsonList.fromJson(Map<String, dynamic> json) {
return JsonList(
result: json['result'],
groupDistinct: json['groupDistinct'],
data: json['data']);
}
}
class _APIState extends State<API> {
JsonList jsonList;
Map<String, dynamic> jsonDataMap;
List<Map> jsonDataMapList;
List name = [];
List part = [];
void initState() {
super.initState();
_getData();
}
Future<JsonList> _getDataJsonList() async {
String url;
url = "";
final response = await http.get(url);
//final response = await http.post(url, body: {"event": event})
if (response.statusCode == 200) {
return JsonList.fromJson(json.decode(response.body));
} else {
// つながらなかった場合のエラー処理
}
}
void _getData() async {
jsonList = await _getDataJsonList();
jsonDataMap = new Map<String, dynamic>.from(jsonList.data[0]);
jsonDataMapList = [jsonDataMap];
for (int i = 1; i < jsonList.data.length; i++) {
jsonDataMapList.add(new Map<String, dynamic>.from(jsonList.data[i]));
}
//取得後実行
setState(() {
this.jsonList = jsonList;
});
}
Widget diologText() {
return Container(
height: 300.0, // Change as per your requirement
width: 300.0, // Change as per your requirement
child: ListView.builder(
itemCount: name == null ? 0 : name.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
new Text("${part[index]}:${name[index]}"),
],
),
);
},
),
);
}
//デザイン部分
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('MyPage 1')),
body: ListView.builder(
itemCount: jsonList == null ? 0 : jsonList.groupDistinct.length,
itemBuilder: (BuildContext context, int index) {
return Card(
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
RaisedButton(
child: Text("${jsonList.groupDistinct[index]}"),
onPressed: () async {
name = [];
part = [];
for (int i = 0; i < jsonDataMapList.length; i++) {
print(jsonList.groupDistinct[index]);
print(jsonDataMapList[0]["group"]);
if (jsonDataMapList[i]["group"] ==
jsonList.groupDistinct[index]) {
name.add(jsonDataMapList[i]["name"]);
part.add(jsonDataMapList[i]["part"]);
}
}
//ダイアログを表示------------------------------------
await showDialog<int>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
title: Text('${jsonList.groupDistinct[index]}'),
content: Container(
child: Column(
children: <Widget>[
diologText(),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('OK'),
onPressed: () => Navigator.of(context).pop(1),
),
],
);
},
);
},
),
],
),
);
},
),
);
}
}