web-dev-qa-db-ja.com

PagedListAdapterアイテムを削除/削除する方法

現在、アプリ開発にAndroidアーキテクチャコンポーネントを使用していますすべてがページングライブラリと連動しています。Pag​​edListAdapterを使用してrecyclerviewアイテムを削除し、データソースを追加するために必要なデータを追加し、データソースリストから更新します。 LiveDataを使用するいいえリストから項目を削除したいnotifyItemRemoved()がPagedListから機能している次の例外が発生しています。

Java.lang.UnsupportedOperationException


Java.util.AbstractList.remove(AbstractList.Java:638)
15
Faris Jameel

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

6
Tyler Bennett

同じ問題がありました。私のPagedListは、DataSourceファクトリーがサーバーからフェッチしたアイテムを表示しました。リストからアイテムを削除する方法を2つ考えました。

  1. リスト全体を再読み込みします。サーバーからアイテムを削除するAPI呼び出しを行ってから、pagedList.dataSource.invalidate()を呼び出します。このソリューションの欠点は、リスト全体がクリアされ、サーバーからすべてのアイテムが受信されることです。正確に私が探していたものではありません。
  2. 結果をRoomに保存します。次に、PagedListはRoomから直接アイテムを取得し、PagedListAdapterはアイテム自体の削除/追加を管理します。

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)を呼び出します

3
cleanOK

Adapter.notifyItemRemoved(position); appDatabase.userDao().deleteUser(user);それは私にとって仕事です!

0
Beyond Chen

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)
        }
0
DungNguyen