【Flutter】Tableで表を表示する

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Flutter】Tableで表を表示する

2024-4-15 | ,

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の形が違うことがあるので、いろいろな形に対応できるようになっておくと吉。