InteractiveViewerで無限スクロールする
InteractiveViewerは、ビューポート(InteractiveViewerの表示領域)のサイズを超える子ウィジェットをスクロール操作できるウィジェットです。ドラッグとズームも可能で便利なウィジェットですが、ビューポートをスクロール可能な範囲の扱いがわかりにくいかもしれません。
デフォルトの挙動
デフォルトの挙動では、ビューポートのスクロール範囲は子ウィジェットの範囲内になります。子ウィジェットの範囲外の余白は表示されず(縮小時を除く)、範囲外にスクロールもできません。画像ビューアーや地図をイメージするとわかりやすいでしょう。
デフォルトのスクロール範囲:
コード:
InteractiveViewer(
// constrainedをfalseにすると、子ウィジェットのサイズが
// ビューポートの範囲を超える場合にスクロール可能になります
constrained: false,
child: Image.asset('images/earth.jpg'),
),
boundaryMargin
余白の幅は、コンストラクタのパラメーター boundaryMargin
で指定できます。デフォルト値は0で、余白は表示されません。
常に余白を用意したい場合は 0 より大きな値を指定します。余白を埋めるウィジェットの指定方法は用意されていないので、Stackなり何なりで背景を用意するといいでしょう。
boundaryMargin
が 100 の挙動:
コード:
InteractiveViewer(
constrained: false,
boundaryMargin: EdgeInsets.all(100),
child: Image.asset('images/earth.jpg'),
),
無限スクロール
boundaryMargin
にinfinityを指定すると余白が無限に生成されるようになり、無限スクロールが可能になります。これに気づくまでずいぶん遠回りしました…
無限スクロールの挙動:
コード:
InteractiveViewer(
constrained: false,
// 余白を無限にする
boundaryMargin: EdgeInsets.all(double.infinity),
child: Image.asset('images/earth.jpg'),
),
注意点として、InteractiveViewer用のスクロールバーのウィジェットは用意されていません。パンやズームに対応するスクロールバーをつけたい場合はScrollbarとの連携を自前で実装する必要があります。ScrollViewと異なり、ScrollbarはInteractiveViewerを囲んでも動作しないので注意してください。
InteractiveViewerを拡張、あるいはラップするパッケージはいくつかあるのですが、決定的なものはないように思えます。InteractiveViewerができることは多く、ユーザーによって要件も様々なので、多くのユーザーが納得する上位互換のウィジェットを作るのは難しそうです。
Discussion