Skip to content

Instantly share code, notes, and snippets.

@Zhuinden
Last active June 20, 2024 14:58
Show Gist options
  • Save Zhuinden/ea3189198938bd16c03db628e084a4fa to your computer and use it in GitHub Desktop.
Save Zhuinden/ea3189198938bd16c03db628e084a4fa to your computer and use it in GitHub Desktop.
Fragment view binding delegate
// https://github.com/Zhuinden/fragmentviewbindingdelegate-kt
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<T : ViewBinding>(
val fragment: Fragment,
val viewBindingFactory: (View) -> T
) : ReadOnlyProperty<Fragment, T> {
private var binding: T? = null
init {
fragment.lifecycle.addObserver(object : DefaultLifecycleObserver {
val viewLifecycleOwnerLiveDataObserver =
Observer<LifecycleOwner?> {
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 }
}
}
fun <T : ViewBinding> Fragment.viewBinding(viewBindingFactory: (View) -> T) =
FragmentViewBindingDelegate(this, viewBindingFactory)
@Zhuinden
Copy link
Author

@ParticleCore i did eventually move this code to a library in https://github.com/Zhuinden/fragmentviewbindingdelegate-kt because these oddities kept coming up inherited from Google's code so it made sense to version it instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment