19

我使用 Paging with Retrofit 从 REST API 加载通知数据列表。

当我按下通知项的删除按钮时,我调用删除 API 将其删除。PagedListAdapter删除 API 响应成功后删除它的正确方法是什么?PagedListPagedListAdapter不支持按索引或对象删除项目。

我试图打电话DataSource.validate(),但它从开始重新加载,而不是从当前页面。

4

2 回答 2

7

根据官方文档

如果您有更精细的更新信号,例如网络 API 发出对列表中单个项目的更新信号,建议将数据从网络加载到内存中。然后通过包装内存快照的 DataSource 将该数据呈现给 PagedList。每次内存中的副本更改时,都会使先前的 DataSource 无效,并且可以创建一个包装快照新状态的新数据源。

PagedList是不可变的,因此您无法对其进行任何修改。你需要做的是:

  1. 维护一个可变列表L,将您的服务器响应存储在您的自定义DataSource.
  2. 将它传递给LoadInitialCallback.onResult()(现在PagedList正在支持L)。
  3. 随心所欲L
  4. 调用DataSource.invalidate()以与新数据源配对,因此DataSource.loadInitial()调用以反映步骤 3 中的更改。
于 2018-08-20T10:07:49.573 回答
2

Not the most elegant solution, but it is working. For example it is much better to use this approach when using Firestore pagination when deleting item instead of re fetching whole list....

Also it can be optimized, because this is just a draft. Main Idea is to use dummy ViewHolder with blank view.

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

于 2020-04-20T15:49:30.137 回答