【问题标题】:How to detect if a fragment is presented or hidden?如何检测片段是呈现还是隐藏?
【发布时间】:2016-08-30 13:44:19
【问题描述】:

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

我正在使用这样的代码向后台堆栈添加片段:

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:从未调用过。许多人在 SO 上说这行得通。但由于某种原因不适合我。
  • setUserVisibleHint:从未调用
  • onStart/onPause 等:它们在这里并不真正适用,因为它们只是反映主机活动的生命周期。

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

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

【问题讨论】:

    标签: android


    【解决方案1】:

    再次编辑 如果您需要回调,您可以像这样覆盖onHiddenChanged:

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

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

    当片段的隐藏状态(由 isHidden() 返回)改变时调用。片段开始时没有隐藏;每当片段改变状态时,都会调用 this。

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

    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

    【讨论】:

    • 何时调用 isVisible?我的片段类在隐藏或可见时需要得到通知。我需要一个回调机制。
    • 他确实在他的问题中说 onHiddenChanged() 没有被调用。
    • onHiddenChanged 永远不会被调用。正如我在问题中所说的那样,我已经尝试过了。
    • @PPartisan 感谢您告诉我,已修复。
    • @RajV 再次修复*
    【解决方案2】:

    来自Android documentation:

    void onStart () 当 Fragment 对用户可见时调用。这 通常与包含 Activity 的 Activity.onStart 相关联 生命周期。

    void onStop () 在 Fragment 不再启动时调用。这是 通常与包含 Activity 的 Activity.onStop 相关联 生命周期。

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

    【讨论】:

    • 这并不完全正确。片段的 onStart/onStop/onResume/onPause 与宿主活动的生命周期相关联。例如,如果一个片段因为另一个片段被压入堆栈顶部而被隐藏,则不会调用 onStop 或 onPause。但是,如果您打开另一个活动,那么它们会被调用。
    【解决方案3】:

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

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {}
    

    【讨论】:

    • setUserVisibleHint 永远不会被调用。正如我在问题中所说的那样,我已经尝试过了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-28
    • 2021-02-09
    • 2011-02-07
    • 2021-11-13
    • 2017-03-20
    • 1970-01-01
    相关资源
    最近更新 更多