findFragmentByTag返回空片段

时间:2016-05-10 10:18:12

标签: android android-fragments

我有这个非常简单的代码:

    InboxFragment ibf = new InboxFragment();
    getFragmentManager().beginTransaction().add(ibf, InboxFragment.TAG);
    getFragmentManager().beginTransaction().commit();

    InboxFragment ib2 = (InboxFragment) getFragmentManager().findFragmentByTag(InboxFragment.TAG);

我不明白为什么我的ib2为空。

在我的活动中管理不同片段的最佳方法是什么?因为我必须实现一个“模板”系统,每个模板都由一个片段表示。我必须在模板之间切换。

  • 第一次声明我的所有片段,并在模板更改时调用好片段。 (如果模板没有改变,请记住任何内容)
  • 模板更改时添加片段。 (当我销毁片段时,我怎么能回想起它,实例存储的地方)。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

See here

  

在使用FragmentTransaction提交FragmentTransaction.commit()之后,计划在进程的主线程上异步执行它。如果要立即执行任何此类挂起操作,可以调用此函数(仅限主线程)。

所以添加这个

在承诺进行此类操作后

.executePendingTransactions()

答案 1 :(得分:1)

每次拨打getFragmentManager().beginTransaction()时,都会创建一个新的FragmentTransaction实例。

您永远不会提交第一笔交易:

  

getFragmentManager()。beginTransaction()。add(ibf,InboxFragment.TAG);

但只有第二个(空):

  

getFragmentManager()的BeginTransaction()提交();

改为写下以下行:

getFragmentManager().beginTransaction().add(ibf, InboxFragment.TAG).commit();

除此之外,如果在添加FragmentManager后立即调用findFragmentByTag()Fragment将返回null,因为默认情况下将异步执行添加Fragment。您可以添加以下语句来强制执行(但可能会导致性能下降):

getFragmentManager().executePendingTransactions();

在您的代码中,您只需编写

即可获得相同的结果(初始化ib2)
ib2 = ibf;

关于您的"模板系统":我认为只创建必要的内容是一种很好的做法。一旦创建了对象,最好保留它们(取决于应用程序)。 Retained Fragments在您的情况下可能会有所帮助,但建议将它们主要用于存储数据,而不是用于保留UI元素。