小ネタサンプルです。
Flutterを書いていて、縦のListViewの中に横にスクロールできるListViewを入れたい、となる時がよくあると思います。以下の図のような実装です。
この場合、横のListViewの高さを固定にする必要があります(viewportエラーが出ます)。
一方、Rowを使えばitemに合わせて高さを柔軟に変更してくれますが、ListViewのようにいい感じにitem間のマージンを空けるのが面倒です。
そこで、マージンを等間隔に置けるRow Widgetを書いてみました。
import 'package:flutter/material.dart'; class EvenlySpacedRow extends StatelessWidget { final List<Widget> children; final int edge; final int spacer; const EvenlySpacedRow({ super.key, required this.children, required this.edge, required this.spacer, }); List<Widget> _buildItem(Widget widget, int position, int length) { if (position == 0) { return <Widget>[ SizedBox( width: edge.toDouble(), ), widget, SizedBox( width: spacer.toDouble(), ), ]; } else if (position == length - 1) { return <Widget>[ widget, SizedBox( width: edge.toDouble(), ), ]; } else { return <Widget>[ widget, SizedBox( width: spacer.toDouble(), ), ]; } } @override Widget build(BuildContext context) { return SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: children .asMap() .entries .map((entry) { return _buildItem(entry.value, entry.key, children.length); }) .expand((e) => e) .toList(), ), ); } }
使用例はこちら。
See the Pen Untitled by あるふぁ2048 (@alpha2048) on CodePen.
スクロール時の追加読み込みなどは実装してませんが、NotificationListenerなどを追加実装すれば実現できそうです。
そもそもListViewの高さを固定にすることでほとんど解決できるかと思いますが、困ったら使ってみてください。