package com.amazon.ivs.multihostdemo.common import android.view.View import androidx.fragment.app.Fragment import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.Observer import androidx.viewbinding.ViewBinding import kotlin.properties.ReadOnlyProperty import kotlin.reflect.KProperty class FragmentViewBindingDelegate( val fragment: Fragment, val viewBindingFactory: (View) -> T ) : ReadOnlyProperty { private var binding: T? = null init { fragment.lifecycle.addObserver(object : DefaultLifecycleObserver { val viewLifecycleOwnerLiveDataObserver = Observer { val viewLifecycleOwner = it ?: return@Observer viewLifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver { override fun onDestroy(owner: LifecycleOwner) { binding = null } }) } override fun onCreate(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.observeForever(viewLifecycleOwnerLiveDataObserver) } override fun onDestroy(owner: LifecycleOwner) { fragment.viewLifecycleOwnerLiveData.removeObserver(viewLifecycleOwnerLiveDataObserver) } }) } override fun getValue(thisRef: Fragment, property: KProperty<*>): T { val binding = binding if (binding != null) return binding val lifecycle = fragment.viewLifecycleOwner.lifecycle if (!lifecycle.currentState.isAtLeast(Lifecycle.State.INITIALIZED)) { throw IllegalStateException("Should not attempt to get bindings when Fragment views are destroyed.") } return viewBindingFactory(thisRef.requireView()).also { this.binding = it } } } /** * Helper delegate for creating a binding and disposing of it appropriately to avoid memory leaks. */ fun Fragment.viewBinding(viewBindingFactory: (View) -> T) = FragmentViewBindingDelegate(this, viewBindingFactory)