我有一个活动以及在框架布局中替换的几个片段。每个片段都包含从XML扩展的布局,并带有许多自定义视图。在这些视图中,我想使用LifecycleObserver在这些视图中订阅生命周期事件。我在科特林的观点:
class MyView(context: Context) : View(context, null, 0): LifecycleObserver {
init {
(getContext() as LifecycleOwner).lifecycle.addObserver(this)
}
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
fun onResume() {
// code
}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
// code
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun onDestroy() {
lifecycle.removeObserver(this)
}
}
问题是,当一个片段消失并被另一个片段替换时,第一个片段中的视图不会收到 onPause 事件。当我从第二个片段返回时,它们也不会得到 onResume 。仅当整个活动暂停时,视图才会收到 onPause ,但它们不了解片段中生命周期的变化。我将其跟踪到布局填充器,该布局填充器用于填充片段的xml布局,它将活动作为 context 参数传递给视图。这是在支持库的Fragment类中实例化布局充气器的方式:
/** @deprecated */
@Deprecated
@NonNull
@RestrictTo({Scope.LIBRARY_GROUP})
public LayoutInflater getLayoutInflater(@Nullable Bundle savedFragmentState) {
if (this.mHost == null) {
throw new IllegalStateException("onGetLayoutInflater() cannot be executed until the Fragment is attached to the FragmentManager.");
} else {
LayoutInflater result = this.mHost.onGetLayoutInflater();
this.getChildFragmentManager();
LayoutInflaterCompat.setFactory2(result, this.mChildFragmentManager.getLayoutInflaterFactory());
return result;
}
}
mHost 是包含此片段的FragmentActivity。因此,传递到片段的onCreateView()中的LayoutInflater包含对FragmentActivity的引用作为上下文。因此,视图有效地观察了Activity的生命周期。
如何让我的自定义视图观察其包含片段的生命周期事件?
答案 0 :(得分:1)
如果仅使用onPause()
和onResume()
,则在View类中覆盖onDetachedFromWindow()
和onAttachedToWindow()
就足够了:
override fun onAttachedToWindow() {
//onResume code
}
override fun onDetachedFromWindow() {
//onPause code
}
您还可以创建自己的生命周期方法:
fun onResume() {}
fun onPause() {}
您可以在片段中保留对视图的全局引用:
//`by lazy` only initializes the variable when it's fist called,
//and then that instance is used for subsequent calls.
//Make sure you only reference `myView` after `onCreateView()` returns
private val myView by lazy { view.findViewById<MyView>(R.id.my_view) }
然后从您的Fragment的onPause()
和onResume()
中,调用View的相应方法:
override fun onPause() {
myView.onPause()
}
override fun onResume() {
myView.onResume()
}
编辑:
要获得可扩展性,请制作自己的min-SDK。创建一个基本的Fragment类:
open class LifecycleFragment : Fragment() {
internal fun dispatchOnResume(parent: View) {
if (parent is CustomLifecycleObserver) parent.onResume()
if (parent is ViewGroup) {
for (i in 0 until parent.childCount) {
dispatchOnResume(parent.getChildAt(i))
}
}
}
internal fun dispatchOnPause(parent: View) {
if (parent is CustomLifecycleObserver) parent.onPause()
if (parent is ViewGroup) {
for (i in 0 until parent.childCount) {
dispatchOnResume(parent.getChildAt(i))
}
}
}
override fun onResume() {
dispatchOnResume(view)
}
override fun onPause() {
dispatchOnPause(view)
}
}
({CustomLifecycleListener
将是您的视图要实现的接口,包含onResume()
和onPause()
方法。)
然后在您的其他片段中扩展该类:
class SomeFragment : LifecycleFragment() {}