我需要从ViewModel中观察一个LiveData在一个RecyclerAdapter ViewHolder中。这背后的原因并不重要。为此,我创建了一个实现LifeycleOwner的自定义ViewHolder,并设法正确地调用生命周期事件,除了lifecycle . state . destroyed">
下面是我最后写的代码:自定义适配器:
abstract class LifecyclePagingDataAdapter<T: Any, VH: LifecycleViewHolder>(diffCallback: DiffUtil.ItemCallback<T>) : PagingDataAdapter<T, VH>(diffCallback) {
override fun onViewAttachedToWindow(holder: VH) {
super.onViewAttachedToWindow(holder)
holder.onAppear()
}
override fun onViewDetachedFromWindow(holder: VH) {
super.onViewDetachedFromWindow(holder)
holder.onDisappear()
}
}
定制ViewHolder:abstract class LifecycleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LifecycleOwner {
private val lifecycleRegistry = LifecycleRegistry(this)
init {
lifecycleRegistry.currentState = Lifecycle.State.INITIALIZED
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
fun onAppear() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
lifecycleRegistry.currentState = Lifecycle.State.RESUMED
}
fun onDisappear() {
lifecycleRegistry.currentState = Lifecycle.State.STARTED
lifecycleRegistry.currentState = Lifecycle.State.CREATED
}
fun onDestroy(){
lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
}
override fun getLifecycle(): Lifecycle {
return lifecycleRegistry
}
}
问题是在哪里调用onDestroy()我的自定义ViewHolder方法?
我是这样使用它的:
class Observer : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
fun onCreate() {}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {}
}
class CountryViewHolder(
private val mBinding: ItemCountryBinding,
onCountryHeaderClicked: (Int, Boolean) -> Unit,
onNearbyChallengeClicked: (Long?) -> Unit,
) : LifecycleViewHolder(mBinding.root){
private var status = STATUS.COLLAPSED
private var layoutStatus = HEIGHT.PENDING
private val viewHolderObserver = Observer()
private val challengesForCountryObserver = Observer<PagingData<ChallengeFullData>> {
lifecycle.coroutineScope.launch {
(mBinding.itemCountryChallengeList.adapter as ChallengesByCountryAdapter).submitData(it)
}
}
init {
lifecycle.addObserver(viewHolderObserver)
}
fun bind(data: TheCounterForCountryRel?, positionExpandedCountry: Int, viewModel: WeakReference<ViewModel>){
val resources = itemView.context.resources
if(data == null){
mBinding.apply {
itemCountryIconExpand.rotation = 0F
itemCountryLabelChallengesQtd.text = resources.getString(R.string.item_country_challenges_qtd_placeholder)
itemCountryLabelName.text = resources.getString(R.string.item_country_label_name_placeholder)
... omitted for simplification ...
Picasso.get()
.load("")
.into(itemCountryPictureFlag)
}
}else{
viewModel.get()?.getLiveDataForCountry(data.country.id)
?.observe(this, challengesForCountryObserver)
.... omitted for simplification ...
}
}
}
这是我的repo,你可以看到我是怎么做的。首先,你必须将parentLifecycleOwner传递给适配器,然后在init块中,你必须观察viewholder的生命周期。
init {
lifecycle.lifecycle.addObserver(object : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
recyclerView?.let { parent ->
val childCount = parent.childCount
for (i in 0 until childCount) {
parent.getChildAt(i)?.let {
(parent.getChildViewHolder(it) as MyViewHolder)
.run {
onDestroy()
}
}
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
fun onStop() {
recyclerView?.let { parent ->
val childCount = parent.childCount
for (i in 0 until childCount) {
parent.getChildAt(i)?.let {
(parent.getChildViewHolder(it) as MyViewHolder)
.run {
onStop()
}
}
}
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun onStart() {
recyclerView?.run {
if (layoutManager is LinearLayoutManager) {
val first =
(layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val last =
(layoutManager as LinearLayoutManager).findLastVisibleItemPosition()
if (first in 0..last)
for (i in first..last) {
findViewHolderForAdapterPosition(i)?.let {
(it as MyViewHolder).onStart()
}
}
}
}
}
})
}
https://github.com/abhinavjiit/baseRecyclerview/blob/master/app/src/main/java/com/example/pristencare/adapter/RecyclerViewImageAdapter.kt