【Flutter】リストに格納された要素を順番にまとめて簡単に表示する方法

2025/01/19に公開

※自分用メモ:Notionで過去に書いたもの

こんにちは、laughtaoneです。
Flutter学習中に備忘録として書いていますので、正確な情報でない可能性もありますのでご了承ください。

実現したいこと

例えば、次のように、情報が格納されたリストがあったとします:

List<String> higedanList = [
  'Same Blue',
  'Subtitle',
  'ミックスナッツ',
  'Pretender',
  'Chessboard',
  '日常',
  '115万キロのフィルム'
];

このリストを元に、次のように Column で順番に、要素を Textで並べたい場合を考えます。

リストのメリットが活かせない対処法

悪い対処法として、次のように、リストの要素へインデックスを手動で指定して実現する方法です。

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text('・ ${higedanList[0]}'),
    Text('・ ${higedanList[1]}'),
    Text('・ ${higedanList[2]}'),
    Text('・ ${higedanList[3]}'),
    Text('・ ${higedanList[4]}'),
    Text('・ ${higedanList[5]}'),
    Text('・ ${higedanList[6]}')
  ]
)
変更前の全体コード
main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    StartPageHome()
  );
}

class StartPageHome extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StartPage(),
    );
  }
}

class StartPage extends StatefulWidget {
  
  _StartPageState createState() => _StartPageState();
}

class _StartPageState extends State<StartPage> {
  List<String> higedanList = [
    'Same Blue', 'Subtitle', 'ミックスナッツ', 'Pretender', 'Chessboard', '日常', '115万キロのフィルム'
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text('・ ${higedanList[0]}'),
            Text('・ ${higedanList[1]}'),
            Text('・ ${higedanList[2]}'),
            Text('・ ${higedanList[3]}'),
            Text('・ ${higedanList[4]}'),
            Text('・ ${higedanList[5]}'),
            Text('・ ${higedanList[6]}')
          ]
        )
      ),
    );
  }
}

この方法の場合、リストの要素数が変化しない場合は問題ありません。
しかし、リストの要素数が変化する場合、対応できず、エラーが出てしまいます。
加えて、Textstyleを後で加えたい時に、同じ style を全ての Text に適用させなければならず、大変効率が悪いです。

効率的な対処法

正しいかどうかは人によりますが、要素数・styleの変化に対応できる、大変効率の良い対処法は、次のように List.generate を用いる方法です:

Column(
  mainAxisAlignment: MainAxisAlignment.center,
  crossAxisAlignment: CrossAxisAlignment.start,
  children: List.generate(higedanList.length, (index) {
    return Text('・ ${higedanList[index]}');
  })
)
変更後の全体コード
main.dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    StartPageHome()
  );
}

class StartPageHome extends StatelessWidget {
  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: StartPage(),
    );
  }
}

class StartPage extends StatefulWidget {
  
  _StartPageState createState() => _StartPageState();
}

class _StartPageState extends State<StartPage> {
  List<String> higedanList = [
    'Same Blue', 'Subtitle', 'ミックスナッツ', 'Pretender', 'Chessboard', '日常', '115万キロのフィルム'
  ];

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.start,
-          children: [
-            Text('・ ${higedanList[0]}'),
-            Text('・ ${higedanList[1]}'),
-            Text('・ ${higedanList[2]}'),
-            Text('・ ${higedanList[3]}'),
-            Text('・ ${higedanList[4]}'),
-            Text('・ ${higedanList[5]}'),
-            Text('・ ${higedanList[6]}')
-          ]
+          children: List.generate(higedanList.length, (index) {
+            return Text('・ ${higedanList[index]}');
+          }
        )
      ),
    );
  }
}

このコードで、List.generate の第1引数に、リストの要素数 higedanList.length を指定することで、要素数の変化に対応することができます。
加えて、Textstyle などを加えたい場合も、return の後の Text に変化を加えるだけで、1つのコードだけで全体に反映させることができます。

まとめ

このようにして、リストに格納された要素を順番にまとめて簡単に表示することができました。

Discussion