从视图中获取当前活动、片段、LifeCycleOwner 的简单方法?

Blc*_*knx 14 android android-lifecycle

编写时ViewsViewModels并且LiveData具有生命周期意识。在ViewModel想是目前的FragmentActivityLiveData当前的LifecycleOwner。您事先不知道您的 View 是否会被包裹或有所包裹。所以它需要一个灵活的函数来找到想要的上下文。我最终采用了这两种方法:

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;
}
Run Code Online (Sandbox Code Playgroud)

现在这是要放入每个视图的大量样板代码。有没有更简单的方法?

我不想为此使用自定义的 View 基类,因为大的层次结构很难看。另一方面,组合需要与此解决方案一样多的代码。

Ahm*_*odi 24

你可以找到它 lifecycle-runtime-ktx

fun View.findViewTreeLifecycleOwner(): LifecycleOwner? = ViewTreeLifecycleOwner.get(this)
Run Code Online (Sandbox Code Playgroud)


Abh*_*tul 5

Kotlin 扩展

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
    }
}
Run Code Online (Sandbox Code Playgroud)

用法

val lifecycleOwner = context.lifecycleOwner()
val fragmentActivity = context.fragmentActivity()
Run Code Online (Sandbox Code Playgroud)

  • 最大深度 = 20 是多少?这只是一个任意数字来减少大循环吗?为什么会有如此多次迭代的循环? (2认同)