7

ColumnやRowで要素ごとに余白を設けたい時使える技

最終更新日 投稿日 2023年10月08日

はじめに

Columnで3個程度同じWidgetを並べる時、Widget間に余白を設けたい場合があります。ListView.separetedのseparatorをColumnでも使いたいみたいな話です。
今回はこういった場合に使える技をいくつか紹介します。

intersperseパッケージを使う

intersperseパッケージを使うとIterableやListの要素の間に要素を挟めます。

以下はReadmeの引用です。
intersperseは要素の間だけ、intersperseOuterは最初と最後にも要素が挟まれてます。

    final list1 = intersperse(2, <int>[]); // [];
    final list2 = intersperse(2, [0]); // [0];
    final list3 = intersperse(2, [0, 0]); // [0, 2, 0];
    final list1Outer = intersperseOuter(2, <int>[]); // [];
    final list2Outer = intersperseOuter(2, [0]); // [2, 0, 2];
    final list3Outer = intersperseOuter(2, [0, 0]); // [2, 0, 2, 0, 2];

拡張関数も用意されており、以下のようにもできます。(こちらも引用)

    final list1 = <int>[].intersperse(2); // [];
    final list2 = [0].intersperse(2); // [0];
    final list3 = [0, 0].intersperse(2); // [0, 2, 0];
    final list1Outer = <int>[].intersperseOuter(2); // [];
    final list2Outer = [0].intersperseOuter(2); // [2, 0, 2];
    final list3Outer = [0, 0].intersperseOuter(2); // [2, 0, 2, 0, 2];

実際に使う

以下のようなWidgetがあったときして

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

  @override
  Widget build(BuildContext context) {
    final list = [1, 2, 3];

    return Column(
      children: list
          .map(
            (e) => Text(e.toString()),
          )
          .toList(),
    );
  }
}

以下のようにすれば余白を追加できます。

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

  @override
  Widget build(BuildContext context) {
    final list = [1, 2, 3];

    return Column(
      children: list
          .map<Widget>(
            (e) => Text(e.toString()),
          )
          .intersperse(
            const SizedBox(
              height: 16,
            ),
          )
          .toList(),
    );
  }
}

intersperseのような関数を独自に定義する

intersperseを使いたくないときは、IterableやListの拡張関数を用意することもできます。
以下のような感じですね。使い方は同じです。

extension ListInsertionExtension<T> on List<T> {
  /// 各要素の間に[value]を挿入します。
  List<T> insertBetween(T value) {
    if (this.isEmpty) return [];

    List<T> result = [];
    for (int i = 0; i < this.length; i++) {
      if (i > 0) {
        result.add(value);
      }
      result.add(this[i]);
    }
    return result;
  }
}

gapパッケージもおすすめ

これまでのサンプルコードで余白を設ける時にSizedBoxをもちいましたが、余白を設ける際はgapというパッケージが使いやすいのでおすすめです。

Gapウィジェットを使うとColumnの中にあるのかRowの中にあるのかを意識せず余白を設けることができます。

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

  @override
  Widget build(BuildContext context) {
    final list = [1, 2, 3];

    return Column(
      children: list
          .map<Widget>(
            (e) => Text(e.toString()),
          )
          .intersperse(
            const Gap(16),
          )
          .toList(),
    );
  }
}

まとめ

ColumnやRowの要素間に余白を設けるときに使える技を紹介しました。

余談

intersperseパッケージの最終更新が古いのが気になるという人もいるかもですが、シンプルな機能のパッケージなので更新の余地が無いだけかと思います🙆‍♂️
image.png

余談2

dartにこういった機能がほしいというIssueがありますが、望みは薄そうです👀

新規登録して、もっと便利にQiitaを使ってみよう

  1. あなたにマッチした記事をお届けします
  2. 便利な情報をあとで効率的に読み返せます
ログインすると使える機能について

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
新規登録
すでにアカウントを持っている方はログイン
7

Qiitaにログインしてダークテーマを使ってみませんか?🌙

ログインするとOSの設定にあわせたテーマカラーを使用できます!