从View中获取当前Activity,Fragment,LifeCycleOwner的简便方法?

时间:2018-03-02 18:41:52

标签: android android-lifecycle

撰写Views时,ViewModelsLiveData感知生命周期ViewModel想要当前FragmentActivityLiveData当前LifecycleOwner。如果您的视图被包裹或有些不确定,您事先不知道。因此,它需要灵活的功能来找到想要的上下文。我最终得到了这两种方法:

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;
}

现在这是一个很多样板代码放到每个View中。有更简单的方法吗?

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

4 个答案:

答案 0 :(得分:5)

Kotlin扩展

date        time
2020-02-01  02:30:00

用法

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
    }
}

答案 1 :(得分:0)

如果您不想使用合成,可以将其放入常见的BaseView类中。另外,您可以在某些utils类中将其设为静态方法。

如果您使用Kotlin,也可以使其成为Kotlin扩展功能,这是我最喜欢的方法。

答案 2 :(得分:0)

类似于另一个答案,但无需指定maxDepth:

 val Context.lifecycleOwner: LifecycleOwner?
    get() {
        var context: Context? = this

        while (context != null && context !is LifecycleOwner) {
            val baseContext = (context as? ContextWrapper?)?.baseContext
            context = if (baseContext == context) null else baseContext
        }

        return if (context is LifecycleOwner) context else null
    }

答案 3 :(得分:0)

你可以找到它 lifecycle-runtime-ktx

fun View.findViewTreeLifecycleOwner(): LifecycleOwner? = ViewTreeLifecycleOwner.get(this)