リストをバウンスしてる時の背景色を指定したい
2020年一発目の記事は Flutter スタートです!
(その前にBitriseからプレゼントもらったやつ書いてたけど...)
やりたいこと
Flutter で ListView
を使うと簡単にリスト表示ができて便利なのですが、
iOS で動かしたときに少し気になることがあります。(Flutterに限った話ではないですが(笑))
リストの1つ目のものをヘッダーという扱いにして、NavigationBar などと同色にした時に、
iOS の場合はリストがバウンスするのでヘッダー部分と NavitaionBar の間に隙間ができて少し気になります。
それをどうにかしたいという話です。
間に見える白が嫌だ!
やったこと
まず思いついたのが、ListView
は背景色が特に指定されていないので、Container
などで背景色を指定してあげて、
各アイテムでは白色を指定すると一応それっぽくはなるのですが、
このやり方だといくつかのケースで不満がのこります。
ListView
の下部までもその影響を受ける- アイテムが少ない場合(画面を越えない場合)はなかなかにきつい結果になる
- 各アイテムで白で背景色を指定するのがだるい。
Divider
とかつかいだすともう。。
というのがあって、他の方法を探すことにしました。
(バウンスさせないようにするっていう解決策がこれでいいなら最も楽で簡単です(笑))
できた方法
そこで、バウンスエリアに該当するところに背景色を指定するためだけに専用の Widget
を追加してそれでやろうという方法です。
この方法でやるとして越える障害(笑)は、バウンスの状況(スクロール位置)を監視しながらそれを埋めるように Widget
を伸縮させるということです。
伸縮させることなくある程度の高さをもたせた Widget
を用意しておけばよさそうだけれども、
もし表示するアイテムが少ない2つとか3つの場合だとそれが見えてしまうという可能性があるのが...
ざっくり考えた方法は
- NavigationBar と
ListView
の間にContainer
を挿入する ScrollController
を使ってスクロールを監視するChangeNotifie
をつかって必要に応じて伝播させる- 差し込んだ
Container
はChangeNotifier
から伝わってきた値をつかって伸縮させる
みたいな感じで実装してみたら、一応できました。
そうそうこんな感じ!
コード
コード全部を一応貼っておきます。
Android だと要らない処理なので、ざっくりきりわけるとしたら
@override
void initState() {
super.initState();
if (Platform.isIOS) {
_controller.addListener(_scrollControllerListener);
}
}
として、iOSのときだけ追加したらスクロールを監視することはなくなるので、
影響を最小限に抑えられそうですか。。ね?
しかし...もっとスマートにできる気がして気が気じゃない(笑)