Flutter-sticky_grouped_listの使用と問題点

リストビューをグループ化したかったので、それ用のパッケージを使うことにした。

一番Likeが多いのはgrouped_list。

grouped_list | Flutter package
A Flutter ListView where the list items can be grouped into sections.

ただ、要件として指定した場所にジャンプしたいというのがあったので、上のパッケージの派生のsticky_grouped_listを使うことにした。

sticky_grouped_list | Flutter package
A ScrollablePositionedList where the list items can be grouped into sections.

今回、sticky_grouped_listで2点ほど問題が出たので、それの解決方法を記述してみた。

grouped_list/sticky_grouped_listについて

こんな感じのグループ化されたリストを簡単に作れるもの。

ListViewはbuilderで上の「item ?」というListTile的なものを何か一つ作るという感じだけど、grouped_listでは、どこからどこまでがグループのListで、そのグループに対してのヘッダー的なウィジェットを作るということができるようになっている。

sticky_grouped_listはさらに指定位置にジャンプするという機能が付与されている。

sticky_grouped_list問題点

ヘッダーの色

Material2のライトで使う分には問題ないのだけど、デフォルトのヘッダー色が「Color(0xffF7F7F7)」の固定色になっているところ。

固定色なので、Material3に変わったり、またダークテーマに変更された場合に、色味がかなり変になる。Material3のライトテーマはなんとなく見ることはできるのだけど。

  • Material2のダークテーマ
  • Material3のライトテーマ
  • Material3のダークテーマ

色味的には灰色。Colors.grey.shade100(0xfff5f5f5)が一番近いか。

実際に使用する場合には、stickyHeaderBackgroundColor:Theme.of(context).colorScheme.surface,と指定するのが一番簡単かな。もしくはこれをベースにちょっと色味を変更するとか。

この場合の色味が以下になる。上からMaterial2のライト・ダーク、Material3のライト・ダーク。



この実装は1.1.0で入れられたらしい。それまでは色は固定でだったようだ。

データ削除時に例外が発生

グルーピングのヘッダーが表示されている状態で、そのグループを削除すると例外が発生する。
以下の様なやつ。

RangeError (index): Invalid value: Not in inclusive range 0..11: 12

例えば、上の様にヘッダーがページ2の物で、その下のページ2に関するリストを削除してsticky_grouped_listを再構築すると発生する。

この件Issuesにあげられているのだけど、初出が2020/10なので3年程放置されている感じなのか。

RangeError (index): Invalid value: Not in inclusive range 0..1: 2 · Issue #26 · Dimibe/sticky_grouped_list
when try to remove item with firestrore and streambuilder

sticky_grouped_listの実装がちょっと複雑だったので、githubをクローンして修正するということはできなかったのだけど、例外箇所を見る限り表示されているヘッダーのリストがなくなった時に発生しているようなので、そうならないような状態にして削除するような実装にして見た。

onPressed: () async {
  if (トップグループじゃない場合) {
    itemScrollController.jumpToElement(
        identifier: 削除するページのひとつ前のページ;
    await Future.delayed(const Duration(milliseconds: 200));
  }
  ページを削除;
},

自分が作成したクラスメソッドなどが入っていた部分は日本語にしてある。

やったことは、まず削除されたページ以外にジャンプしてから削除するという感じのもの。
ジャンプ後すぐ削除すると、実際の移動処理はされないので例外が出てしまうので、ここにdelayを入れてジャンプ処理が完了してから削除するようにした点。

上の実装、リストの最後尾にジャンプするのと同じような感じの実装かな。

コメント

タイトルとURLをコピーしました