web-dev-qa-db-ja.com

DataSource.Invalidate()の後、新しいPagedListには1つのページしかありません

Pagingライブラリを使用して実装したページネーションのリストがあります。このリストの項目は変更(変更/削除)できます。公式 documentation によると、私は最初にメモリ内のリストキャッシュを変更し、そこからDataSourceがページを取得し、その後datasource.invalidate()を呼び出して新しいペア_PagedList/DataSource_を作成します:

ネットワークAPIがリスト内の単一のアイテムへの更新を通知するなど、より詳細な更新信号がある場合は、ネットワークからメモリにデータをロードすることをお勧めします。次に、メモリ内のスナップショットをラップするDataSourceを介して、そのデータをPagedListに提示します。インメモリコピーが変更されるたびに、invalidate以前のDataSourceと、スナップショットの新しい状態をラップする新しいデータソースを作成できます。

ユーザーが最初のページでアイテムを変更した場合、それは機能し、よく見えます。

ただし、ユーザーがdatasource.invalidate()の実行中に2ページ目以降にいる場合、最初のページの終わりにスローされますになります。

これは、新しいPagedListが_PagedListAdapter.submitList_に送信されたときに最初のページのみが含まれているために発生します。アダプターは新旧のリストを比較し、最初のページ以外のすべてのアイテムを削除します。これは常に発生しますが、ユーザーが最初のページにいる場合は表示されません。

したがって、私には、新しいペア_PagedList/DataSource_が前のペアをフェッチしたページ数を認識していないように見え、datasource.invalidate()はドキュメントの状況に適合しません。ケースで許容できると思われる動作の場合、ユーザーはすべてのリストを更新します(スワイプして更新など)が、

リスト内の単一のアイテムへの更新

誰かがそのような問題に直面したり、どういうわけか私が欲しいものをアーカイブしたことがありますか?たぶん、すべてのページで新しいPagedListを取得するのに役立ついくつかのトリックがありません。

説明のために:ライブラリバージョン_2.1.0_。インメモリキャッシュとリモートサービスに基づくカスタムPageKeyedDataSourceRoomなし)

8
ylus

誰かが興味を持っている場合に備えて、私の研究を共有したいと思います。

  1. 問題(「機能の欠如」)は既知であり、少なくとも公式トラッカーでいくつかの関連するディスカッションを見つけました onetwo
  2. PositionalDataSourceまたはItemKeyedDataSourceを使用している場合は、 this answer が示すように、初期パラメーターから_requestedStartPosition/requestedInitialKey_の方向に掘る必要があります。ソリューション全体を構築する時間はあまりありませんでしたが、無効化後の初期ロードでは、これらのパラメーターは実際には異なります

私のケースについて:PageKeyedDataSourceここ このタイプのデータソースにはrequestedInitialKey paramsに類似するものがないと読むことができます。それでも、私に合う解決策を見つけましたが、非常に単純ですが、汚いトリックのように感じます。

loadInitial()が呼び出された後、invalidate()のメモリ内キャッシュは、最初のページだけでなく、既にロードされているすべてのページを返します。最初は、たとえばrequestedLoadSizeが5で、結果が50のアイテムリストである場合に何かが壊れるのではないかと心配していましたが、それは単なるヒントであり、無視できます。最初のページではなく、最後にキャッシュされたページに対応するnextPageKeyを渡すことを忘れないでください。

それが役に立てば幸い

6
ylus

監視可能なメソッドでは、最初のページのリストアイテムのみを取得します。他のアイテムを編集する場合は、adapter.currentlistメソッドでそのリストを取得できます。

例:

 private fun list():MutableList<String>{
    val list = mutableListOf<String>()
        for (value in videosAdapter.currentList.orEmpty()) {
            val abc = value.snippet.resourceId.videoId
            list.add(abc)
        }
    return list
}
0
Hussnain Haidar