【Flutter】Columnの中にListViewを入れ、ListViewだけでなく全体をスクロールさせる方法

こんにちは、株式会社Pentagonでアプリ開発をしている山田です。
https://pentagon.tokyo

開発をしていると、ColumnにListViewを入れた場合、ListView部分が全体スクロールと同期させてスクロールさせたいけど、ListViewのみスクロールしてしまい、解決に時間がかかりました。

今回はその解決方法をお伝えできたらと思います。

目次

問題となった現象

以下の様に別でScrollViewが別で動いている現象を解決したいと思います。ColumnにListを入れると、上部上部が固定されていることがわかります。

サンプル画面

以下のようなサンプル画面を作りたいと思います。


このように、Listを入れても部分的にスクロールせず、同期したスクロールができるようにします。

コード

以下がサンプル画面の全体コードになります。

import 'dart:core';

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    String appTitle = 'Sample Code';

    return MaterialApp(
      title: appTitle,
      home: Scaffold(
        appBar: AppBar(
          title: Text(appTitle),
        ),
        body: MyPage(),
      ),
    );
  }
}

class MyPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _listContentViews(),
    );
  }
}

Widget _listContentViews() {
  return CustomScrollView(slivers: [
    SliverToBoxAdapter(
      child: Container(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
            Text('test 1'),
          ],
        ),
      ),
    ),
    _itemView(),
  ]);
}

Widget _itemView() {
  List items = [];

  for (int i = 0; i < 100; i++) {
    items.add(i);
  }

  return SliverList(
    delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
      return Text(
        'Text${items[index]}',
      );
    }, childCount: items.length),
  );
}

解説

まず、CustomScrollViewの中にSliverToBoxAdapter を入れます。このCustomScrollViewを指定することにより、Widget内をスクロールできるようにします。
そして、SliverToBoxAdapter の中にColumnを追加することによって、自分の表示させたいレイアウトにすることができます。

その下に、ListViewを追加したい場合、SliverList を用います。そこでdelegate: SliverChildBuilderDelegate を設定して、Listを表示させます。

参考資料

SliverToBoxAdapter

SliverList

採用情報はこちら
目次