REST APIから通知データのリストをロードするために、レトロフィット付きのページングを使用しました。
通知項目の削除ボタンを押すと、削除APIを呼び出して削除します。削除API応答の成功後にPagedListAdapter
からそれを削除する適切な方法は何ですか? PagedList
またはPagedListAdapter
は、インデックスまたはオブジェクトによるアイテムの削除をサポートしていません。
DataSource.validate()
を呼び出そうとしましたが、現在のページからではなく、最初からリロードします。
公式ドキュメント によると:
ネットワークAPIがリスト内の単一のアイテムへの更新を通知するなど、より詳細な更新信号がある場合は、ネットワークからメモリにデータをロードすることをお勧めします。次に、メモリ内のスナップショットをラップするDataSourceを介して、そのデータをPagedListに提示します。インメモリコピーが変更されるたびに、以前のDataSourceを無効にし、スナップショットの新しい状態をラップする新しいデータソースを作成できます。
PagedList
は不変であるため、変更することはできません。あなたがする必要があるのは:
L
を維持し、サーバー応答をカスタムDataSource
に保存します。LoadInitialCallback.onResult()
に渡します(PagedList
はL
によってサポートされています)。L
に好きなことをしてください。DataSource.invalidate()
を呼び出して新しいデータソースとペアリングするため、DataSource.loadInitial()
が呼び出され、手順3の変更が反映されます。最もエレガントなソリューションではありませんが、機能しています。たとえば、リスト全体を再フェッチするのではなく、アイテムを削除するときにFirestoreページネーションを使用する場合は、このアプローチを使用する方がはるかに優れています。
これは単なるドラフトなので、最適化することもできます。主なアイデアは、空白のビューでダミーのViewHolderを使用することです。
class PostAdapter(
options: FirestorePagingOptions<Post>,
private val feedViewModel: FeedViewModel
) : FirestorePagingAdapter<Post, RecyclerView.ViewHolder>(options) {
companion object {
private const val DELETED_VIEW_TYPE = 1
private const val NORMAL_VIEW_TYPE = 2
}
private val deletedItems = arrayListOf<String>()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val inflater = parent.getLayoutInflater()
return when (viewType) {
NORMAL_VIEW_TYPE -> {
PostViewHolder(ItemPostBinding.inflate(inflater, parent, false))
}
else -> BindingViewHolder<ItemDeletedPostBinding>(
ItemDeletedPostBinding.inflate(inflater, parent, false)
)
}
}
override fun getItemViewType(position: Int): Int {
val item = getItem(position)?.toObject(Post::class.Java)
if (deletedItems.firstOrNull { it == item?.postId }.isNotNull()) {
return DELETED_VIEW_TYPE
} else {
return NORMAL_VIEW_TYPE
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int, model: Post) {
if (holder is PostViewHolder) {
holder.bind(model, feedViewModel)
}
}
fun deleteItem(post: Post) {
val postId = post.postId
if (postId != null) {
val element = currentList?.find { it.toObject(Post::class.Java)?.postId == postId }
val index = currentList?.indexOf(element)
index?.let {
deletedItems.add(postId)
notifyItemChanged(it)
}
}
}
}