6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ModalBottomSheetのChildでScrollableなViewを使う

Posted at

showModalBottomSheetがお手軽便利だったのでメモ。

ソースコード


showModalBottomSheet<void>(
  context: context,
  isScrollControlled: true,
  shape: RoundedRectangleBorder(
    borderRadius: BorderRadius.vertical(top: Radius.circular(16.0)),
  ),
  builder: (context) => DraggableScrollableSheet(
    expand: false,
    builder: (context, scrollController) {
      return ListView.builder(
        controller: scrollController,
        itemCount: 20,
        itemBuilder: (context, position) {
          return ListTile(title: Text('${position.toString()}'),);
        },
      );
    },
  ),
);

こんな感じのコードで、ModalBottomSheetを表示しつつスクロール可能な場合はスクロールさせつつ、スクロールがTopの場合はドラッグでBottomSheetが閉じていくUIを表現できる。

  • ModalBottomSheen.isScrollControlled = trueにする
  • DraggableScrollableSheet.expand = falseにする
  • DraggableScrollableSheetのbuilderから渡されるscrollControllerを、ScrollViewのcontrollerに渡す

この辺りがポイント。
また、DraggableScrollableSheetのinitialChildSizemaxChildSizeminChildSizeの値を調整することでBottomSheetの位置を調整できる。

余談

ちょっと残念な点として、このコードだといわゆるsnapping的な動きは表現できないので、maxChildSizeとminChildSizeの間みたいな中途半端な位置でも、BottomSheetがその高さで止まってしまい、どっちかに吸い付くみたいにはならない。

snappingな動作を表現したい場合は、素直にsliding_up_panelなどのパッケージを使うか、DraggableScrollableNotificationを監視して頑張る(draggable_snappable)など、工夫する必要がある。
自分の場合は、手の込んだ変なパッケージ作ったりもした(scrollable_panel)

「GoogleMapのみたいに動いてほしい!」みたいな要件が無い限りはModalBottomSheetで済ませて、どうしてもって時は各種パッケージを導入するのが楽そう。

6
3
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
6
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?