撰写Views
时,ViewModels
和LiveData
感知生命周期。 ViewModel
想要当前FragmentActivity
,LiveData
当前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基类,因为大型层次结构很难看。另一方面,组合需要与此解决方案一样多的代码。
答案 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)