How to observe LiveData inside Custom View

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

Answers 1

  • 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 getLifecycle() = lifecycleRegistry
    
        override fun onAttachedToWindow() {
            super.onAttachedToWindow()
            lifecycleRegistry.currentState = Lifecycle.State.RESUMED
        }
    
        override fun onDetachFromWindow() {
            super.onDetachFromWindow()
            lifecycleRegistry.currentState = Lifecycle.State.DESTROYED
        }
    
    
        
        val myObserver = Observer<Long>{
            //whatever
        }
    
        init{
            liveData.observe(this, myObserver}
        }
    }
    

Related Articles