当使用新的分页库更新单个元素时,最好的方法是什么?
假设我们有一个谷歌示例Paging with network,使用PageKeyedSubredditDataSource
。想象一下,我们想要更改RedditPost
的一个单独元素。因此,我们想要检查它是否在列表中,如果是,则更新它。更新不应该像调用invalidate()那么容易,这将调用第一页(可能RedditPost在第5页)。我们只想更新一个元素,而不是所有元素。
当使用新的分页库更新单个元素时,最好的方法是什么?
假设我们有一个谷歌示例Paging with network,使用PageKeyedSubredditDataSource
。想象一下,我们想要更改RedditPost
的一个单独元素。因此,我们想要检查它是否在列表中,如果是,则更新它。更新不应该像调用invalidate()那么容易,这将调用第一页(可能RedditPost在第5页)。我们只想更新一个元素,而不是所有元素。
ViewHolder
以成为LifeCycle Owner
,因为默认情况下已经对Activities
和Fragments
进行了扩展。
LifecycleViewHolder
:abstract class LifecycleViewHolder(itemView: View) :
RecyclerView.ViewHolder(itemView),
LifecycleOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
fun onAttached() {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START)
}
fun onDetached() {
lifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
}
override fun getLifecycle(): Lifecycle = lifecycleRegistry
}
LifecycleOwner
是一个只有一个方法的接口,表示该类具有 Lifecycle
。您可以在此处找到更多信息。
LifecyclePagedListAdapter
:
abstract class LifecyclePagedListAdapter<T, VH : LifecycleViewHolder>(diffCallback: DiffUtil.ItemCallback<T>) :
PagedListAdapter<T, VH>(diffCallback) {
override fun onViewAttachedToWindow(holder: VH) {
super.onViewAttachedToWindow(holder)
holder.onAttached()
}
override fun onViewDetachedFromWindow(holder: VH) {
super.onViewDetachedFromWindow(holder)
holder.onDetached()
}
}
如果需要,可以使用LifecycleAdapter
:
abstract class LifecycleAdapter<VH : LifecycleViewHolder> :
RecyclerView.Adapter<VH>() {
override fun onViewAttachedToWindow(holder: VH) {
super.onViewAttachedToWindow(holder)
holder.onAttached()
}
override fun onViewDetachedFromWindow(holder: VH) {
super.onViewDetachedFromWindow(holder)
holder.onDetached()
}
}
MyAdapter
扩展为LifecyclePagedListAdapter<MyEntity, LifecycleViewHolder>(MY_COMPARATOR)
,将MyViewHolder
扩展为LifecycleViewHolder(view)
。您需要根据我们所做的更改完成类。现在,我们可以观察MyViewHolder
类上的liveData
对象。因此,我们可以将其添加到MyViewHolder
类中(假设您正在使用依赖注入)。基本上,我们将执行与Fragments
或Activities
相同的操作:private lateinit var myViewModel: MyViewModel
init {
(itemView.context as? AppCompatActivity)?.let{
myViewModel = ViewModelProviders.of(it).get(MyViewModel::class.java)
}
}
bind()
方法内部:fun bind(myCell: MyEntity?) {
myViewModel.myLiveData.observe(this, Observer {
// Buala!! Check if it is the cell you want to change and update it.
if (it != null && myCell != null && it.id == myCell.id) {
updateCell(it)
}
})
}
invalidate()
方法来更新它们,这将导致当前加载的所有页面无效,从而触发新数据的加载。此外,如果您想确保某些数据更新被立即应用于用户界面,则可以在数据源上调用invalidate()
,然后再次调用loadAfter()
或loadBefore()
以重新获取数据。 - pskink