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のinitialChildSize
やmaxChildSize
、minChildSize
の値を調整することでBottomSheetの位置を調整できる。
余談
ちょっと残念な点として、このコードだといわゆるsnapping的な動きは表現できないので、maxChildSizeとminChildSizeの間みたいな中途半端な位置でも、BottomSheetがその高さで止まってしまい、どっちかに吸い付くみたいにはならない。
snappingな動作を表現したい場合は、素直にsliding_up_panelなどのパッケージを使うか、DraggableScrollableNotificationを監視して頑張る(draggable_snappable)など、工夫する必要がある。
自分の場合は、手の込んだ変なパッケージ作ったりもした(scrollable_panel)
「GoogleMapのみたいに動いてほしい!」みたいな要件が無い限りはModalBottomSheetで済ませて、どうしてもって時は各種パッケージを導入するのが楽そう。