はじめに
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パッケージの最終更新が古いのが気になるという人もいるかもですが、シンプルな機能のパッケージなので更新の余地が無いだけかと思います🙆♂️
余談2
dartにこういった機能がほしいというIssueがありますが、望みは薄そうです👀
コメント