【Flutter】SliverAppBarとTabBarを組み合わせたときに各タブのスクロール位置を保持したい
Flutterでは伸び縮みするApp Barを使うのも簡単に実装できます。
でも、タブを表示して中にListViewなどを表示すると、各タブ内のスクロール位置が連動してしまいました…。 例えば、1つ目のタブのリストでスクロールして2つ目のタブに切り替えると、そのタブでも同じ位置までスクロールした状態になっています。
やり方が悪い可能性も考えて公式ドキュメントでコード例を探してみたところ、NestedScrollView のところにありました。
PageStorageKeys are used to remember the scroll position of each tab's list.
「各タブのリストのスクロール位置を保つには PageStorageKeys を使います」と書かれています。 実現したいのはまさにこれです。
上のリンク先に書かれている例は DefaultTabController
以下のみの断片的なコードなので、動くコードにして試しました。
できた!
と一瞬思ったのですが、ぬか喜びでした。
- Tab1 で Item 3 までスクロール
- Tab2 で Item 5 までスクロール
- 各タブで Item 3、Item 5、Item 0 の位置になっている(ここまでOK)
- Tab3 で Item 8~9 あたりまでスクロール
- Tab2 が Item 14 までスクロールしてしまっている
- Tab2 で Item 12 まで戻す
- Tab1 も Tab3 も先頭(Item 0)まで戻ってしまっている
公式ドキュメントのサンプルでも起こるならFlutter自体のバグですね。
なお、この問題は既に報告されていました。
Issue の報告者自身が解決策を書いていますが、Pull Request ではなく新たなパッケージのような形にされています。 また、それを使ってみましたが解決しませんでした。 使い方の理解が足りないのかそのパッケージの問題なのかわかりません。 Flutter 本体が修正されるのはまだ先になりそうです。
改善されたかも(2019/6/27 追記)
数ヶ月前
同じコードを実行すると、上記のおかしな挙動の頻度が減っていて、少し改善されているようでした。
本日
久しぶりに再び実行してみたところ、しばらく操作しても再現しませんでした。
見落としかもしれませんが、GitHub の Issues や Releases にも関連情報が見当たりません。
完全に直ったとは判断できませんが、そろそろ使っても良さそうです。