Android FragmentTransaction提交是在什么时候?

48

我正在开发一个平板应用。该应用有一个包含两个片段的活动。第一个片段是一个“已知列表”片段,从数据库查询结果中显示一个简单的单项布局列表,第二个片段显示所选记录的详细信息(来自列表片段)。第二个片段的类型取决于在列表中显示的记录。例如,如果记录是客户,则显示所选客户的详细信息;如果记录是库存物品,则显示所选物品的详细信息等。 为了与详细信息片段通信,我创建了一个接口,每个详细信息片段类都实现该接口。 列表片段在布局 XML 中被“固定”在活动中。但是详细信息片段是在活动创建期间像这样创建的:

super.onCreate(savedInstanceState);
setContentView(R.layout.act_hlpfiles_host);

...

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.laydetailsfragment, FragmentsPool.getHelperFileFragment(501), "recordDetails");
fragmentTransaction.commit();

myDetailsFragment = getFragmentManager().findFragmentByTag("recordDetails");

...

myListFragment = (frg_hlpfiles_lstrecords) getFragmentManager().findFragmentById(R.id.frg_lstrecords);

....
}
这段代码的问题在于 myDetailsFragment 一直为空。这是因为 fragmentTransaction.commit() 不会立即运行,而是在主线程准备好下一次运行时发生(正如Android文档所述)。
如果我在 onStart() 中创建细节片段,并在 onCreate() 中实例化列表片段,则一切正常。
因此问题是:我如何确保 fragmentTransaction.commit() 已经提交了事务,以便可以对添加的片段进行一些处理?此外,是否有办法等待提交完成,然后继续执行其余的代码?
4个回答

107

尝试在提交事务后但在按标签查找之前运行fragmentManager.executePendingTransactions(),看看是否能够解决您的问题。


2
嘿,马克!猜猜怎么着!它正常工作了。现在我有另一个问题要问你,你能告诉我为什么我读了3-4次FragmentTransaction的文档来找到解决方案,但我从未查看过FragmentManager的文档吗? :-) - ChD Computers
2
我很高兴它能够正常工作。但是文档还需要更加连贯和直观一些... - Mark D

10

你在哪里找到关于 .commitNow() 新方法的源代码? - prGD
@prGD,有多个传言说了这件事情,有人在源代码中发现了它,并最终在2016年Google I/O上宣布了它。 - Ostap Andrusiv
@prGD 它可从API 24中获取。它在参考文献中:https://developer.android.com/reference/android/app/FragmentTransaction.html#commitNow() - Ostap Andrusiv
当调用 DialogFragment.Show() 方法时,一个人将如何利用它? - Zapnologica

1
我遇到了类似的问题。
我认为这里的关键是使用commitNow()而不是commit()与getSupportFragmentManager一起使用。这将禁止主线程执行,直到片段被销毁。在构建界面和使用共享活动时非常重要。我应该知道它让我困惑了一段时间!
以下是一个示例代码: getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.fragment_frame)).commitNow();

0

"...所以我可以使用添加的片段进行一些工作?此外,是否有任何方法可以等待提交完成,然后继续执行其余代码?"

这完全取决于您想要做什么工作。从您的问题中,我看到大部分工作代码应该在您的片段代码中,例如当选择库存项目时。

在回调中,当选择列表项被选中(为了更改详细信息片段),您将能够轻松地获得详细信息片段。

此外,您已经通过FragmentsPool.getHelperFileFragment(501)的返回获得了片段,因此我不明白为什么您需要通过标签获取片段。

我很想知道您需要在onCreate中使用添加的详细信息片段来做什么工作。


首先感谢您的回答。实际上,大部分工作都是在活动代码中完成的(新记录、保存、删除等)。您建议的方法非常正确,但我的应用程序有点更复杂,我希望通过标签获取详细信息片段的原因是,有时我需要知道最后一个显示的详细信息片段在更改为FragmentsPool.getHelperFileFragment(<listID>)之前是什么,以便创建返回堆栈。在onCreate中,我只是根据一个ListID初始化活动的第一个“外观”。我问题中的代码是简化的,不完整的。 - ChD Computers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接