👨‍👧

flutter で widget を独自クラスに切り出す方法

2021/02/05に公開

まぁそうだよねって感じなんですが
当然のことすぎるのか意外と情報なかったので書きました

TL;DR

  • widget を独自クラスに切り出すときは extends で継承して super で親クラスのコンストラクタを呼び出してあげればOK

例えばこんなとき

たとえば PageViewchildren を事前に widget の配列で定義しておく時に
こう書いたとします。

final pageList = [
Column(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    SizedBox(
      height: 150,
      child: Center(
        child: Text(
          '説明1のタイトル',
          style: const TextStyle(
            fontSize: 24,
            color: Colors.black54,
          ),
        ),
      ),
    ),
    Padding(
      padding: const EdgeInsets.only(
        top: 30,
      ),
      child: SizedBox(
        width: 300,
        child: Text(
          '説明1説明1説明1説明1説明1説明1説明1説明1説明1',
          style: const TextStyle(
            fontSize: 14,
            color: Colors.black54,
          ),
        ),
      ),
    ),
  ],
),
Column(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    SizedBox(
      height: 150,
      child: Center(
        child: Text(
          '説明2のタイトル',
          style: const TextStyle(
            fontSize: 24,
            color: Colors.black54,
          ),
        ),
      ),
    ),
    Padding(
      padding: const EdgeInsets.only(
        top: 30,
      ),
      child: SizedBox(
        width: 300,
        child: Text(
          '説明2説明2説明2説明2説明2説明2説明2説明2説明2',
          style: const TextStyle(
            fontSize: 14,
            color: Colors.black54,
          ),
        ),
      ),
    ),
  ],
),
Column(
  mainAxisAlignment: MainAxisAlignment.start,
  children: [
    SizedBox(
      height: 150,
      child: Center(
        child: Text(
          '説明3のタイトル',
          style: const TextStyle(
            fontSize: 24,
            color: Colors.black54,
          ),
        ),
      ),
    ),
    Padding(
      padding: const EdgeInsets.only(
        top: 30,
      ),
      child: SizedBox(
        width: 300,
        child: Text(
          '説明3説明3説明3説明3説明3説明3説明3説明3説明3',
          style: const TextStyle(
            fontSize: 14,
            color: Colors.black54,
          ),
        ),
      ),
    ),
  ],
),
];

ほげえぇぇぇだっせえええええwww
普段プログラミングしててもこんなこと書かないだろ!となって腹立ちますね。
同じこと書きたくない病が発症します。
ので、独自の別クラスに切り出してやりましょう。
じゃあどうするのか?

こうする

まず新しいファイルを作ります。

で、切り出した widget を独自クラスで定義します。
どこで切り出してもいいんですが、切り出すところの widget を extends で継承してやって
super で親クラスのコンストラクタを呼び出してあげればOKです。
今回は Column を継承して独自クラスにしました。

Column コンストラクタで使わないが
その配下の widget に流し込みたいもの(今回は title, instruction といった文字列)も
切り出したクラスのコンストラクタで受け取ってやればいいだけです。
widget 作成に BuildContext が必要なのであれば
BuildContext もコンストラクタに渡してやりましょう。

※記事を書いてる途中にサンプルコードをいじったので
 この widget であれば BuildContext は使わないコードになってしまいました……
 ご容赦ください💦

class Instruction extends Column {
  Instruction(
      BuildContext context, String title, String instruction)
      : super(
          mainAxisAlignment: MainAxisAlignment.start,
          children: [
            SizedBox(
              height: 150,
              child: Center(
                child: Text(
                  title,
                  style: const TextStyle(
                    fontSize: 24,
                    color: Colors.black54,
                  ),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(
                top: 30,
              ),
              child: SizedBox(
                width: 300,
                child: Text(
                  instruction,
                  style: const TextStyle(
                    fontSize: 14,
                    color: Colors.black54,
                  ),
                ),
              ),
            ),
          ],
        );
}

あとはそれを呼び出してやればいいだけです。

final pageList = [
  Instruction(
    context,
    '説明1のタイトル',
    '説明1説明1説明1説明1説明1説明1説明1説明1説明1',
  ),
  Instruction(
    context,
    '説明2のタイトル',
    '説明2説明2説明2説明2説明2説明2説明2説明2説明2',
  ),
  Instruction(
    context,
    '説明3のタイトル',
    '説明3説明3説明3説明3説明3説明3説明3説明3説明3',
  ),
];

簡単ですね!

今回は widget の配列で定義している widget を切り出しましたが、
Scaffoldbody に指定する中の widget や
StatelessWidgetbuild() で返す widget の部分など
どこでも切り出すことができます。

flutterのコードがネスト地獄みたいになってる人は
構造が把握できなくならない程度にやっていきましょう。

Discussion