How to observe LiveData inside Custom View

Viewed 2225

How should I observe a LiveData in a Custom View. I tried to cast it's context as lifecycleOwner but it makes some problems and doesn't work in all cases. I tried to put a setter but it doesn't work either

1 Answers

Views do not have lifecycle on their own. There are two approaches that a personally use, they are actually the same thing but one of them is adding a lifecycle while the other is. without a lifecycle.

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

This method manually observe/remove on attach/detach to window. I prefer it when I'm observing few livedata and it's simple/limited


Another option is to turn our custom view into a LifecycleOwner. I recommend this method BaseCustomViews and some extremely huge and complicated views (like a Map navigation view)

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.DESTROYED
    }


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

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