When writing Views
, ViewModels
and LiveData
are lifecycle aware. The ViewModel
want's the current FragmentActivity
, LiveData
the current LifecycleOwner
. You don't know in advance if your View will be wrapped or somewhat. So it requires a flexible function to to find the wanted context. I ended up with this two methods:
private FragmentActivity getFragmentActivity() {
Context context = getContext();
while (!(context instanceof FragmentActivity)) {
context = ((ContextWrapper) context).getBaseContext();
}
return (FragmentActivity) context;
}
private LifecycleOwner getLifecycleOwner() {
Context context = getContext();
while (!(context instanceof LifecycleOwner)) {
context = ((ContextWrapper) context).getBaseContext();
}
return (LifecycleOwner) context;
}
Now this is a lot of boilerplate code to put into each View. Is there a more easy way?
I don't want to use a customised View base class for this, as large hierarchy's are ugly. Composition on the other hand requires as much code as this solution.
Fragment and View STARTED When the fragment becomes STARTED , the onStart() callback is invoked.
When using a ViewModel exposing LiveData s for a Fragment , there are currently two LifecycleOwners that can be used to oberve: the Fragment itself or. the Fragment 's property mViewLifecycleOwner .
These files contain only the onCreateView() method to inflate the UI of the fragment and returns the root of the fragment layout. If the fragment does not have any UI, it will return null.
you can find it
lifecycle-runtime-ktx
:
fun View.findViewTreeLifecycleOwner(): LifecycleOwner? = ViewTreeLifecycleOwner.get(this)
Kotlin Extensions
fun Context.fragmentActivity(): FragmentActivity? {
var curContext = this
var maxDepth = 20
while (--maxDepth > 0 && curContext !is FragmentActivity) {
curContext = (curContext as ContextWrapper).baseContext
}
return if(curContext is FragmentActivity)
curContext
else
null
}
fun Context.lifecycleOwner(): LifecycleOwner? {
var curContext = this
var maxDepth = 20
while (maxDepth-- > 0 && curContext !is LifecycleOwner) {
curContext = (curContext as ContextWrapper).baseContext
}
return if (curContext is LifecycleOwner) {
curContext as LifecycleOwner
} else {
null
}
}
Usage
val lifecycleOwner = context.lifecycleOwner()
val fragmentActivity = context.fragmentActivity()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With