-
-
Save Zhuinden/ea3189198938bd16c03db628e084a4fa to your computer and use it in GitHub Desktop.
// 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) |
How would I use this in DialogFragment?
I just don't use this in a DialogFragment.
@Zhuinden Isn't it possible to add support for it, or have a similar solution for it?
@AndroidDeveloperLB There are two "flavors" of DialogFragment
, they have different view lifecycle. You can find examples for both cases here.
@gmk57 Oh these make sense. Thank you!
sounds like you are missing
val binding = binding
in youronViewCreated
OR you are actually accessing the view afteronDestroyView
and potentially have a memory leak in your app anyway.
Btw there is an updated version of this gist as a library in https://github.com/Zhuinden/fragmentviewbindingdelegate-kt
@Zhuinden what is the real reason behind val binding = binding
in most cases we directly access binding. is this required ? .
@manju23reddy I debugged a guy's code who had trouble with callbacks of a WebView running on a different thread and this was the fix, so I do do it in my code personally.
I haven't tried this. I have just tested it with fragments and that works. Try to use fragment and see if it works. @Drjacky