Sliverを使用したUI実装におけるHeaderの実装方法について

こんにちは。最近AndroidからFlutterでの開発に移転した、エキサイト株式会社の奥田です。

今回のブログ内容は前回の記事の続編ですのでSliverの基本的な実装は下記のブログを閲覧していただけると幸いです。

tech.excite.co.jp

本題になりますが、今回はSliverを使用したUIでSliverToBoxAdapterを使用し、Headerを実装する方法について記述します。

実装したものがこちらになります。 f:id:pomupomupurinkun:20220210105339p:plain

動作バージョン

  • Flutter 2.8.1
  • Dart 2.15.1

SliverToBoxAdapterを使用した理由

A sliver that contains a single box widget.

ドキュメントに記載されているように単一のBoxを含むWidgetであるとわかります。

Headerを使用する場合に使用するには適していると判断しました。(StickyHeader等を実装する場合は別途実装方法を検討する必要があります。)

詳しくはドキュメントを閲覧していただけると幸いです。

api.flutter.dev

実装部分について

class CollapsingList extends StatelessWidget {
  const CollapsingList({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    final gridListItem = [
      Container(color: Colors.red, height: 150.0),
      Container(color: Colors.purple, height: 150.0),
      Container(color: Colors.green, height: 150.0),
      Container(color: Colors.orange, height: 150.0),
      Container(color: Colors.yellow, height: 150.0),
      Container(color: Colors.pink, height: 150.0),
      Container(color: Colors.cyan, height: 150.0),
      Container(color: Colors.indigo, height: 150.0),
      Container(color: Colors.blue, height: 150.0),
    ];

    final listItem = [
      Container(color: Colors.red),
      Container(color: Colors.purple),
      Container(color: Colors.green),
      Container(color: Colors.orange),
      Container(color: Colors.yellow),
    ];

    return CustomScrollView(
      slivers: [
        const _RowHeader(title: 'SliverGrid'),
        SliverGrid.count(
          crossAxisCount: 3,
          children: gridListItem,
        ),
        const _RowHeader(title: 'SliverFixedExtentList'),
        SliverFixedExtentList(
          itemExtent: 150.0,
          delegate: SliverChildListDelegate(listItem),
        ),
      ],
    );
  }
}

class _RowHeader extends StatelessWidget {
  const _RowHeader({
    Key? key,
    required this.title,
  }) : super(key: key);

  final String title;

  @override
  Widget build(BuildContext context) {
    return SliverToBoxAdapter(
      child: Padding(
        padding: const EdgeInsets.symmetric(
          horizontal: 8.0,
          vertical: 4.0,
        ),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            Text(title),
            TextButton(
              onPressed: () { },
              child: const Text('確認用'),
            )
          ],
        ),
      ),
    );
  }
}

今回の上記の実装内容で記事の初めに掲載したUIの実現ができます。

_RowHeader部分でHeaderに表示するボタン、テキストを実装しています。SliverToBoxAdapterの要素を変更することでテキストのみ、さらに複雑なUIの実装など柔軟にUIを実装することができます。

気になる方は是非お手元の環境で試してみてください。

まとめ

今回はSliverToBoxAdapterを使用することでHeaderを実装しました。複雑なUIになってもSliverGrid、SliverListやSliverToBoxAdapterなどを併用して使用することで実装できそうだなと感じています。要件を達成するために既存のWidgetと比較して、使い分けができれば選択肢が広がるなとも考えています。

最後に

弊社では絶賛採用強化中です。もしご興味がある方がいましたら下記リンクよりアクセスいただけると幸いです。(カジュアルからもOKです)

www.wantedly.com