【问题标题】:Getting reference to nested fragment from FragmentTabHost从 FragmentTabHost 获取对嵌套片段的引用
【发布时间】:2013-04-09 09:26:16
【问题描述】:

在我的应用程序中,我使用了一个Activity,其中包含一个FragmentFragmentTabHost,因此它的所有选项卡都是nested Fragments

在一个Activity 中,它包含一个Fragment 及其nested Fragment,我们可以使用onAttachedFragment() 获得对附加一个的引用。

但是如何从FragmentTabHost 获得对nested Fragment 的引用?

【问题讨论】:

    标签: android android-fragments android-tabhost android-nested-fragment


    【解决方案1】:

    好吧,探索FragmentTabHost的源代码我发现,当它添加一个片段选项卡时,它会将TabSpec的标签分配给嵌套的Fragment

    所以要获得对这个 Fragment 的引用,我们应该调用

    getChildFragmentManager().findFragmentByTag(tabSpecTag)

    【讨论】:

    • 你能把代码贴在你做映射的地方吗,因为我总是在我的参考上得到 NullPointerException
    • @Ravi,我在我的片段 onActivityCreated() 方法中添加了这段代码,我得到了对这个片段的引用
    • 你在哪个对象上调用 getChildFragmentManager() ?
    • 我在父 Fragment 中调用它。
    • @ono 好像你调用了不正确的 fragmentManager 尝试getChildFragmentManager() 而不是getSupportFragmentManager()
    【解决方案2】:

    我尝试了一段时间,但我从FragmentManager 返回了null,因为我试图在添加后立即访问onCreateView() 中的管理器。

    Here is a good explanation on what happened

    还需要注意的是,尚未选择的Fragment 选项卡在FragmentManager 中尚不存在,因此也将返回null。在尝试使用FragmentManager 访问Fragment 之前,我通过调用mTabHost.setCurrentTab(index) 解决了这个问题。它不是很干净,但它可以工作。

    【讨论】:

    • 好吧,我在父 Fragment 的生命周期开始时在 onViewCreated() 中获得了对嵌套 Fragment 的引用,检查 savedInstanceState 捆绑包是否为空 - 在这种情况下我知道Fragment 应该默认出现并使用特定的标签,在其他情况下,我从这个包中得到一个 int 值,它代表我之前保存在那里的选中选项卡,并使用它来强制转换为特定的片段类。此外,我使用传递给onTabChanged() 方法的TabSpec 的标签为OnTabChangeListener 分配嵌套选项卡引用。
    【解决方案3】:

    以上解决方案也有效,但我有一个更简单的解决方案,

     @Override
    public void onTabChanged(final String tabId) {
    
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
    
                mFragment = getChildFragmentManager().findFragmentByTag("Tagname");
            }
        },1000);
    }
    

    这里你必须实现 FragmentTabHost.onTabChangeListener 我们在从 childFragmentManager 获取片段时保持了第二次延迟。

    注意:你需要将你使用过的片段转换成 mFragment。

    【讨论】:

    • 有一件事,至少我认为是一个缺点,就是在这里你会造成潜在的内存泄漏,为匿名Handler 对象分配内存。在被调用后,它会保持对外部类的引用大约一秒钟。因此,如果您在更改选项卡后立即退出活动,您仍然会在内存中对它有一个悬空引用。如果您在 Activity 类中调用此代码,您应该三思而后行。此外,如果用户决定使用您的标签并随机滑动它们,那么您将使用Runnables 淹没您的消息队列,并且无法将它们从Handler中删除。
    • 同意你的观点,但我想从哪里得到正确的位置来调用这个方法 mFragment = getChildFragmentManager().findFragmentByTag("Tagname"); ...这是我找到解决方案的代码。感谢您的深入评论:)
    【解决方案4】:

    我找到了一个我更喜欢的解决方案,因为它不涉及延迟执行代码(考虑到 android 硬件碎片和不同的处理器速度,这总是不确定的)。

    在您的 onTabChanged() 方法中,在您尝试查找片段之前,请在与您的 tabHost 关联的片段管理器上调用 executePendingTransactions()。似乎 FragmentTabHost 源代码中有一些地方应该调用 executePendingTransactions() 但没有这样做。

    每次选项卡更改一个异常时,这都会起作用...选择的第一个选项卡仍然返回 null...在我的特定情况下,无论如何我都能够通过在 onResume 中放置一些代码来以不同的方式处理此异常.

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多