kotlin 如何在自定义视图中观察LiveData [已关闭]

q3qa4bjr  于 2023-03-30  发布在  Kotlin
关注(0)|答案(1)|浏览(146)

已关闭。此问题需要details or clarity。当前不接受答案。
**想要改进此问题?**添加详细信息并通过editing this post阐明问题。

两年前关闭了。
Improve this question
我应该如何在自定义视图中观察LiveData。我试图将其上下文转换为lifecycleOwner,但它产生了一些问题,并且在所有情况下都不起作用。我试图放置一个setter,但它也不起作用

7z5jn7bk

7z5jn7bk1#

视图本身没有生命周期。我个人使用的方法有3种,它们实际上是一样的,但其中一种是添加生命周期,而其他的没有生命周期。

class MyCustomView  @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
): View(context, attrs, defStyleAttr){
    
    
    val myObserver = Observer<Long>{
        //whatever
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        liveData.observeForever(myObserver)
    }

    override fun onDetachFromWindow() {
        super.onDetachFromWindow()
        liveData.removeObserver(myObserver)
    }
}

这个方法在附加/分离到窗口时手动观察/移除。当我观察很少的实时数据时,我更喜欢它,它很简单/有限
另一个选择是将我们的自定义视图转换为LifecycleOwner。我推荐这个方法用于BaseCustomViews和一些非常巨大和复杂的视图(如Map导航视图)。此外,请记住,您需要手动通知视图其父视图被销毁(您可以直接调用该方法或使用视图树导航来为BaseCustomView的所有子视图调用此函数)。

abstract class BaseCustomView  @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
): View(context, attrs, defStyleAttr), LifecycleOwner {
    protected val lifecycleRegistry = LifecycleRegistry(this);

    override fun getLifecycle() = lifecycleRegistry
    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        lifecycleRegistry.currentState = Lifecycle.State.RESUMED
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        lifecycleRegistry.currentState = Lifecycle.State. CREATED
    }

    @CallSuper
    open fun destroyLifecycle(){
        lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
    }

    
    val myObserver = Observer<Long>{
        //whatever
    }

    init{
        liveData.observe(this, myObserver}
    }
}

如果您更喜欢第一种方法,另一种选择是将这两种方法结合起来,使用BaseCustomView,使其子对象能够轻松地观察LiveData。

abstract class BaseCustomView  @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
): RelativeLayout(context, attrs, defStyleAttr) {

    //a list to hold the list of observers and their LiveData
    private val autoObservers = ArrayList<Pair<LiveData<*>, Observer<*>>>()

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        for((liveData, observer) in autoObservers){
            liveData.observeForever(observer as Observer<in Any>)
        }
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        for((liveData, observer) in autoObservers){
            liveData.removeObserver(observer as Observer<in Any>)
        }
    }

    protected fun<T : Any> LiveData<T>.observe( observer: Observer<T> ){
        autoObservers.add(this to observer)

        //if it's not attached, onAttachedToWindow will do the observation
        if(isAttachedToWindow){
            observeForever(observer)
        }
    }
}

相关问题