FlutterのTable
で表を表示したい!
概要
今回の記事では、FlutterのTable
で表を表示する手順を掲載する。
仕様書
環境
- Android Studio Giraffe | 2023.2.1 Patch 2
- Flutter 3.19.6
手順書
データ構造の違う2パターンの例を挙げる。
パターン1: 行毎のオブジェクトの配列
こんな感じで行毎のオブジェクトの配列になってるJSONをTable
で表示する。
[
{'ID': '1', 'Name': 'ジョバンニ', 'HP': '30'},
{'ID': '2', 'Name': 'カムパネルラ', 'HP': '24'},
{'ID': '3', 'Name': 'ザネリ', 'HP': '37'},
]
列も行も全て表示する例。
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
body: const TableSample1()
)
)
);
}
class TableSample1 extends StatelessWidget {
const TableSample1({super.key});
@override
Widget build(BuildContext context) {
final List<Map<String, String>> table = [
{'ID': '1', 'Name': 'ジョバンニ', 'HP': '30'},
{'ID': '2', 'Name': 'カムパネルラ', 'HP': '24'},
{'ID': '3', 'Name': 'ザネリ', 'HP': '37'},
];
List<String> headers = table[0].keys.toList();
return SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Table(
border: TableBorder.all(),
columnWidths: {
for (int i = 0; i < headers.length; i++) i: const FlexColumnWidth(),
},
children: [
TableRow(
decoration: BoxDecoration(color: Colors.grey[300]),
children: headers.map((header) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
header,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.bold),
),
);
}).toList(),
),
...table.map((row) {
return TableRow(
children: headers.map((header) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
row[header]!,
textAlign: TextAlign.center,
),
);
}).toList(),
);
}).toList(),
],
),
),
),
);
}
}
列名を指定して表示する例。列の順番変えたり出来る。
import 'package:flutter/material.dart';
class TableSample1 extends StatelessWidget {
const TableSample1({super.key});
@override
Widget build(BuildContext context) {
final List<Map<String, String>> table = [
{'ID': '1', 'Name': 'ジョバンニ', 'HP': '30'},
{'ID': '2', 'Name': 'カムパネルラ', 'HP': '24'},
{'ID': '3', 'Name': 'ザネリ', 'HP': '37'},
];
List<String> headers = table[0].keys.toList();
return SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Table(
border: TableBorder.all(),
columnWidths: {
for (int i = 0; i < headers.length; i++) i: const FlexColumnWidth(),
},
children: [
TableRow(
decoration: BoxDecoration(color: Colors.grey[300]),
children: headers.map((header) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
header,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.bold),
),
);
}).toList(),
),
...table.map((row) {
return TableRow(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item['Name']!),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item['ID']!),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(item['HP']!),
),
],
);
}).toList(),
],
),
),
),
);
}
}
パターン2: 列毎のオブジェクトの配列
こんな感じで列毎のオブジェクトの配列になってるJSONをTable
で表示する。
[
{'ID': ["1", "2", "3"]},
{'Name': ["ジョバンニ","カムパネルラ","ザネリ"]},
{'HP': ["30","24","37"]},
]
列も行も全て表示する例。
class TableSample2 extends StatelessWidget {
const TableSample2({super.key});
@override
Widget build(BuildContext context) {
final List<Map<String, List<String>>> table = [
{'ID': ["1", "2", "3"]},
{'Name': ["ジョバンニ","カムパネルラ","ザネリ"]},
{'HP': ["30","24","37"]},
];
List<String> headers = table.map((map) => map.keys.first).toList();
int rowCount = table.first.values.first.length;
return SafeArea(
child: Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Table(
border: TableBorder.all(),
columnWidths: {
for (int i = 0; i < headers.length; i++) i: const FlexColumnWidth(),
},
children: [
TableRow(
decoration: BoxDecoration(color: Colors.grey[300]),
children: headers.map((header) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
header,
textAlign: TextAlign.center,
style: const TextStyle(fontWeight: FontWeight.bold),
),
);
}).toList(),
),
...List.generate(rowCount, (i) {
return TableRow(
children: [
for (int j = 0; j < headers.length; j++)
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
table[j][headers[j]]![i],
textAlign: TextAlign.center,
),
),
],
);
}).toList(),
],
),
),
),
);
}
}
まとめ(感想文)
例えば、APIによって返ってくるJSONの形が違うことがあるので、いろいろな形に対応できるようになっておくと吉。