現在、アプリ開発にAndroidアーキテクチャコンポーネントを使用していますすべてがページングライブラリと連動しています。PagedListAdapterを使用してrecyclerviewアイテムを削除し、データソースを追加するために必要なデータを追加し、データソースリストから更新します。 LiveDataを使用するいいえリストから項目を削除したいnotifyItemRemoved()がPagedListから機能している次の例外が発生しています。
Java.lang.UnsupportedOperationException
Java.util.AbstractList.remove(AbstractList.Java:638)
PagedList
にあるデータを直接変更することはできないので、不変だと思います。この状況でアイテムの削除を実装するための鍵は、バッキングデータセットこれまでに受信したすべてのデータを表すコードのどこかに。 ArrayList
がうまくいきました。
アイテムを削除する場合は、バッキングデータセットからアイテムを削除し、データソースでinvalidateを呼び出します。これにより、loadInitial()
呼び出しがトリガーされ、バッキングデータセットをcallback.onResult()
関数に渡すことができます。 PagedListAdapter
は、提供されたDiffUtil.ItemCallback
を使用して、データが更新されたことをスマートに判断し、それに応じて自身を更新します。
このチュートリアルは、ページングライブラリの使用中にアイテムを適切に削除するために使用する正しいフローを理解するのに役立ちました: https://medium.com/@FizzyInTheHall/implementing-swipe-to-delete-with-Android- architecture-components-a95165b6c9bd
チュートリアルに関連付けられているリポジトリは、次の場所にあります。 https://gitlab.com/adrianhall/notes-app
同じ問題がありました。私のPagedListは、DataSourceファクトリーがサーバーからフェッチしたアイテムを表示しました。リストからアイテムを削除する方法を2つ考えました。
pagedList.dataSource.invalidate()
を呼び出します。このソリューションの欠点は、リスト全体がクリアされ、サーバーからすべてのアイテムが受信されることです。正確に私が探していたものではありません。DAOオブジェクト内
_("SELECT * FROM YourModel")
fun getAll(): DataSource.Factory<Int, YourModel>
@Delete
fun delete(item: YourModel)
_
ユーザーがリストをスクロールするときにデータベースを更新するために、BoundaryCallbackを実装しました。 DBに表示する項目がなくなったときに呼び出され、同じページの最後に呼び出すことができるため、同じリクエストを数回実行しないようにしました(私の場合、リストのキーはページ番号です)。
_class YourModelBoundaryCallback(private val repository: Repository) : PagedList.BoundaryCallback<YourModel>() {
private val requestArray = SparseArray<Disposable>()
private var nextPage = 1
private var lastPage = 1
override fun onZeroItemsLoaded() {
if (requestArray.get(1) == null) {
requestArray.put(1, repository.getFirstPage()
.subscribe({
lastPage = it.total / PAGE_SIZE + if (it.total % PAGE_SIZE == 0) 0 else 1
nextPage++
}))
}
}
override fun onItemAtEndLoaded(itemAtEnd: YourModel) {
if (nextPage > lastPage) {
return
}
if (requestArray.get(nextPage) == null) {
requestArray.put(nextPage, repository.getNextPage(nextPage)
.subscribe({
lastPage = it.total / PAGE_SIZE + if (it.total % PAGE_SIZE == 0) 0 else 1
nextPage++
}))
}
}
override fun onItemAtFrontLoaded(itemAtFront: YourModel) {
// ignored, since we only ever append to what's in the DB
}
}
_
PagedListインスタンスはこれになりました
_private val pagedListConfig = PagedList.Config.Builder()
.setEnablePlaceholders(false)
.setPrefetchDistance(3)
.setPageSize(PAGE_SIZE)
.build()
val pagedList = LivePagedListBuilder(yourModelDao.getAll(), pagedListConfig)
.setBoundaryCallback(YourModelBoundaryCallback(repository))
.build()
_
最後に、アダプターからアイテムを削除するには、yourModelDao.remove(yourModel)
を呼び出します
Adapter.notifyItemRemoved(position); appDatabase.userDao().deleteUser(user);
それは私にとって仕事です!
Pojoオブジェクトに設定されたフラグに基づいて、notifyItemUpdated()を呼び出してリスト内のアイテムを一時的に非表示にします
if(data?.hasVisible == false) {
itemBinding.root.visibility = View.GONE
itemBinding.root.layoutParams = RecyclerView.LayoutParams(0, 0)
}else{
itemBinding.root.visibility = View.VISIBLE
itemBinding.root.layoutParams = RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT,
RecyclerView.LayoutParams.WRAP_CONTENT)
}