我有一个应用程序,与布局。 在肖像画中,我在屏幕上有一个碎片,在陆地 - 两个。
在OnCreate of my Activity中:
frameDetailsFragment = (FrameLayout) findViewById(R.id.detailsFragment);
if (frameDetailsFragment != null){
if (EntryPool.getPool(this).getEntries().size() > 0) {
detailsFragment = DetailsFragment.newInstance(EntryPool.getPool(this).getEntries().get(0));
getFragmentManager().beginTransaction()
.add(R.id.detailsFragment, detailsFragment, DETAILS_FRAGMENT)
.commit();
}
}
因此,当我们处于肖像时,我们不会创建DetailsFragment。 在DetailsFragment中没有什么有趣的,没有setRetainState,我也没有在onAtach()中保存活动。我只是注销了生命周期方法。 因此,当我在portarit中启动应用程序时,它可以正常工作(不会创建详细信息碎片)。然后我旋转 - 细节碎片是装箱。 然后我再次旋转 - 我看到了:
04-22 12:06:42.737 2692 2692 I ANT DetailsFragment :: onDestroy
04-22 12:06:42.737 2692 2692 I ANT DetailsFragment :: onDetach
04-22 12:06:42.761 2692 2692 I ANT DetailsFragment :: onAttach
04-22 12:06:42.761 2692 2692 I ANT DetailsFragment :: onCreate
04-22 12:06:42.805 2692 2692 D ANT MainActivity oncretae
04-22 12:06:42.845 2692 2692 I ANT DetailsFragment :: onCreateView
04-22 12:06:42.857 2692 2692 I ANT DetailsFragment :: onActivityCreated
正如我们所见,frag重新创建了bu片段管理器。为什么?请帮助我,我在这种行为中看不到任何逻辑 - 我没有写过setRetainInstanse,也没有在执行添加片段事务时添加addToBack
答案 0 :(得分:1)
既然你的问题是为什么会这样,(以及其他答案是关于如何阻止它):
这是因为Activity不知道何时从已保存的实例状态恢复Fragment不再需要Fragment。如果在活动恢复视图层次结构后,有一个视图与最初添加片段的ID相同(transaction.add中的第一个参数),那么它将在轮换更改后重新添加。
答案 1 :(得分:0)
在清单文件中添加以下代码,您在其中声明要从中调用fragment的活动:
android:configChanges="keyboardHidden|orientation|screenSize"
答案 2 :(得分:0)
您的片段中应该setRetainInstance
到true
public void setRetainInstance (boolean retain)
控制是否在活动重新创建(例如从配置更改)中保留片段实例。这只能用于不在后栈中的片段。如果设置,则重新创建活动时片段生命周期将略有不同:
onDestroy()
将不会被调用(但onDetach()
仍将是,因为片段正在与其当前活动分离)。
因为片段没有被重新创建,所以不会调用onCreate(Bundle)。
<{1}}和onAttach(Activity)
)仍会被调用。
答案 3 :(得分:0)
我决定了这个问题 - 在OnSaveInstance状态下,我只需使用片段管理器删除片段(如果存在):
@Override
protected void onSaveInstanceState(Bundle outState) {
if (detailsFragment != null) {
getFragmentManager().beginTransaction()
.remove(detailsFragment)
.commit();
}
super.onSaveInstanceState(outState);
}
在这个钩子的帮助下,只有当它通过onCreate检查时,该片段才会在Activity中再次创建:
if (frameDetailsFragment != null){
if (EntryPool.getPool(this).getEntries().size() > 0) {
detailsFragment = DetailsFragment.newInstance(EntryPool.getPool(this).getEntries().get(0));
getFragmentManager().beginTransaction()
.add(R.id.detailsFragment, detailsFragment, DETAILS_FRAGMENT)
.commit();
}
但可以肯定的是,必须有更好的解决方案,只有从onCreate调用它才能强制执行片段以使其失效,重新分配并且永不重新创建