如何检测片段是否呈现或隐藏?

Raj*_*ajV 5 android

我正在维护片段的后堆栈,并在按下“后退”按钮时弹出堆栈。每当片段可见时,我都需要重新加载数据,并在隐藏时进行一些清理。为此,我需要检测何时显示和隐藏片段。这是一个非常常见的问题,但是令人惊讶的是,没有一个答案对我有用。一世

我正在使用如下代码向后台添加片段:

public void pushFragment(Fragment f) {
    getFragmentManager().beginTransaction()
            .add(R.id.content_frame, f, null)
            .addToBackStack(null)
            .commit();
}
Run Code Online (Sandbox Code Playgroud)

我使用以下代码弹出片段:

public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 1) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图从一个片段类中检测它何时变得可见或隐藏(因为它是从堆栈中弹出或另一个片段被推到顶部)。到目前为止,我已经尝试过这些回调:

  • onViewCreated / onDestroyView:仅在将片段添加到堆栈并从堆栈弹出时调用。当片段由于堆栈上的其他片段而隐藏或可见时不调用。
  • onHiddenChanged:从未调用。因此,许多人都说这可行。但是由于某种原因而不为我工作。
  • setUserVisibleHint:从未调用
  • onStart / onPause等:它们在这里并没有真正应用,因为它们只是反映了主机活动的生命周期。

是否存在Fragment回调,让我检测何时显示或隐藏了片段?我宁愿不使用Backstack侦听器,因为我希望每个片段类都具有自己的显示/隐藏逻辑。

编辑: 如果我replace()用来添加片段(而不是add()),则先前显示的片段的视图将被破坏。结果,如果该片段再次出现在堆栈顶部,则将重新创建其视图。在这种情况下,每次显示或隐藏片段时,都会调用onViewCreated / onDestroyView或onStart / onStop。我想我可以使用这种方法。缺点是视图是经常创建和销毁的。在这种情况下,我不妨使用活动而不是片段进行主从导航。

Nir*_*uan 4

再次编辑 如果您需要回调,您可以重写onHiddenChanged,如下所示:

public void onHiddenChanged(boolean hidden) {
if(hidden){// Do you stuff here}
} 
Run Code Online (Sandbox Code Playgroud)

正如 PPartisan 提到的,您声称onHiddenChanged从未调用过它。
原因是第一次显示片段时不会被调用onHiddenChanged

当片段的隐藏状态(由 isHidden() 返回)发生更改时调用。碎片一开始就没有隐藏;每当片段改变状态时都会调用它。

要解决此问题:将其添加到您的代码中:

FragmentTransaction mFragmentTransaction = getFragmentManager().beginTransaction();
if (f!= null) {
        mFragmentTransaction .hide(f);
    }
mFragmentTransaction.add(R.id.content_frame, f, null)
mFragmentTransaction.addToBackStack(null)
mFragmentTransaction.commit();
Run Code Online (Sandbox Code Playgroud)

有关此SO 线程的更多信息