11
7

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

Last updated at Posted at 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がありますが、望みは薄そうです👀

11
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7