スクロールしても画像が上部に固定して残るようにしたい
ざっくりまとめ。
- スクロールしても画像を画面上部にある程度大きさで残したい
SliverAppBar
を使うとできた- pinned の設定をする
- bottom の設定をする
です。
環境
- Flutter v1.5.4-hotfix.2
- Dart v2.3.0
やりたいこと
画像を表示してスクロールしても画面上部に固定されて残したい。
どんなもんかは見てもらったほうが早いので
こういうやつです。
実装
SliverAppBar
というものを使います。
CustomScrollView
で利用できる Widget のようなので、ListView
を使っている場合は移行が必要。
とはいっても大体同じ構造で使えるので変えるのは簡単です。
まずは最小構成で
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
expandedHeight: 200,
flexibleSpace: Image.asset('assets/cover.jpg', fit: BoxFit.cover),
),
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(padding: EdgeInsets.all(16.0), child: Text('Row_$index'));
}),
)
],
)
SliverAppBar
をとりあえず使ってみようとした場合はこの様な感じでいけます。
これを実行すると...
これだけでも悪くはないですが、せっかく表示しているいい感じの画像がリストのスクロールとともに消えてしまうのが寂しいです(笑)
画像をのこす
SliverAppBar
を上部に残し続けるのも簡単で pinned
プロパティを設定してあげるとできます。
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true, // <- 追加
expandedHeight: 200,
flexibleSpace: Image.asset('assets/cover.jpg', fit: BoxFit.cover),
),
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(padding: EdgeInsets.all(16.0), child: Text('Row_$index'));
}),
)
],
)
pinned: true
を追加しました。
これで実行すると....
スクロールしても SliverAppBar
が消えることなく残り続けます。
だいぶ良くなってきましたが、これだと画像領域がちょっと小さすぎる。
画像なのだから NavigationBar の height よりかはも少しほしいところです。
minimum height の設定をする
とはいっても、minHeight みたいなプロパティはないのですこしひねった方法で実現します。
bottom というプロパティがあるので、こちらに最小の高さを維持できるように何もない Widget を設定しておくことで、
minHeight みたいな挙動をさせます。
CustomScrollView(
slivers: <Widget>[
SliverAppBar(
pinned: true,
expandedHeight: 200,
flexibleSpace: Image.asset('assets/cover.jpg', fit: BoxFit.cover),
bottom: PreferredSize(child: Text(''), preferredSize: Size.fromHeight(60),), // <- 追加
),
SliverList(
delegate: SliverChildBuilderDelegate((BuildContext context, int index) {
return Container(padding: EdgeInsets.all(16.0), child: Text('Row_$index'));
}),
)
],
)
bottom: PreferredSize(child: Text(''), preferredSize: Size.fromHeight(60),)
を追加しました。
この Size.fromHeight(60)
の部分が最小の高さを維持する役割になります。
最終的にはこの値と NavigationBar のものを足した高さが残ることになります。
これで実行すると、最初に紹介したものになります👍
コード
一応サクッとコピペで試せるように全部のっけておきます。
参考
- SliverAppBar class - material library - Dart API
pinned
floating
snap
を設定した場合の動画があったり手厚い :kami: - Feature Request: SliverAppBar should have the ability to set minimum height · Issue #21298 · flutter/flutter
bottom を使えば!というのはこちらから :pray: