😇

List.generateの使い道

2024/07/06に公開

📕Overview

https://api.flutter.dev/flutter/dart-core/List/List.generate.html
https://www.youtube.com/watch?v=izr7uBuiacE

既知の長さのコールバックを使用した値のリストを生成する場合は、List.generateを使用します。Generateは、リストを作成し指定された数の項目をそれに埋め込むリストクラスの名前付きコンストラクタです。項目は、項目のインデックスに引数として渡されるコールバック関数を使用して生成されます。

Flutterでは、List.generateは、行と列の同様の子ウイジェットのリストを作成する場合、特にリストビューのスクロール機能が必要ない場合、または様々な関連ウィジェットを組み合わせる場合に役立ちます。例えば、テキストとボタンの値に5つのアイコンがある書評アプリ用のUI要素を構築していると想像してください。

テキストウィジェット、ボタン、および5つのアイコンボタンを子にもつ行を作成することもできますが、これはエラーが発生しやすく、保守が困難です。代わりに、List.generateコンストラクタを使用して、この行にネストされるアイコンボタンウイジェットのリストを作成する必要があります。

この例では、5つの要素のための余地を持って作成する必要があります。そして、インデックスごとにジェネレーターメソッドが呼び出され、インデックスが引数としてジェネレーターに渡されます。この生成されたアイコンのリストを使用して書評UI要素の例をリファクタリングし、コードをより保守しやすくすることができます。

この例では、スプレッド演算子を使用して、1つのリスト(5つの星のアイコン)を別のリストに簡潔に埋め込みます。コードはよりドライで、読みやすく、保守しやすくなりました。

🧷summary

5つの要素だけ生成したい。こんかいは動画を参考に、星を5個生成するロジックをつくって見ました。

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const ListGenerateExample(),
    );
  }
}

class ListGenerateExample extends StatefulWidget {
  const ListGenerateExample({super.key});

  
  State<ListGenerateExample> createState() => _ListGenerateExampleState();
}

class _ListGenerateExampleState extends State<ListGenerateExample> {
  int selectedIndex = 0; // selectedIndexをクラスのメンバ変数として定義

  
  Widget build(BuildContext context) {
    final stars = List.generate(5, (int index) {
      return StartIcon(
        selected: index < selectedIndex, // 選択された星より小さいインデックスの星を選択状態に
        onPressed: () {
          setState(() {
            selectedIndex = index + 1; // タップされた星の次のインデックスを選択状態にする
          });
        },
      );
    });
    return Scaffold(
      appBar: AppBar(
        title: const Text('List Generate Example'),
      ),
      body: Center(
        child: Padding(
          padding: const EdgeInsets.only(left: 10, right: 10),
          child: Container(
            width: double.infinity,
            height: 50,
            decoration: BoxDecoration(
              border: Border.all(color: Colors.black),
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text('評価'),
                ...stars,
                TextButton(onPressed: () {}, child: const Text('評価する ')),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class StartIcon extends StatelessWidget {
  const StartIcon({required this.selected, required this.onPressed, super.key});

  final bool selected;
  final VoidCallback onPressed;

  
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(selected ? Icons.star : Icons.star_border),
      color: Colors.yellow,
      onPressed: onPressed,
    );
  }
}

🧑‍🎓thoughts

今回は、List.generateの使い方について解説してみました。あらかじめ表示する要素の数が決まっている場合は、こちらを使って、ウイジェットの表示をやってみると良さそうです。仕事で何度か使ったことあったのですが、なんとなく、決まった数だけ生成して、[...変数名]で使ってるのだなと理解しておりました😅

Discussion