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

时间:2016-08-30 13:44:20

标签: android

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

我正在使用这样的代码向backstack添加片段:

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

我正在使用此代码弹出片段:

public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 1) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

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

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

是否有片段回调可以让我检测片段何时被显示或隐藏?我宁愿不使用backstack监听器,因为我希望每个片段类都有自己的show / hide逻辑。

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

3 个答案:

答案 0 :(得分:3)

再次修改 如果您需要回调,可以覆盖onHiddenChanged,如下所示:

public void onHiddenChanged(boolean hidden) {
if(hidden){// Do you stuff here}
} 

正如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();

有关此SO thread

的详情

答案 1 :(得分:-1)

来自Android documentation

  

void onStart()当片段对用户可见时调用。这个   通常与包含Activity的Activity.onStart绑定   的生命周期。

     

void onStop()在片段不再启动时调用。这是   通常绑定到包含Activity的Activity.onStop   的生命周期。

正确的方法是使用Fragment Lifecycle的方法。

答案 2 :(得分:-2)

这被调用然后片段正在改变可见性

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {}