在不需要方向更改时重新创建片段

时间:2015-04-22 12:09:46

标签: android android-fragments

我有一个应用程序,与布局。 在肖像画中,我在屏幕上有一个碎片,在陆地 - 两个。

在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

4 个答案:

答案 0 :(得分:1)

既然你的问题是为什么会这样,(以及其他答案是关于如何阻止它):

这是因为Activity不知道何时从已保存的实例状态恢复Fragment不再需要Fragment。如果在活动恢复视图层次结构后,有一个视图与最初添加片段的ID相同(transaction.add中的第一个参数),那么它将在轮换更改后重新添加。

答案 1 :(得分:0)

在清单文件中添加以下代码,您在其中声明要从中调用fragment的活动:

android:configChanges="keyboardHidden|orientation|screenSize"

答案 2 :(得分:0)

您的片段中应该setRetainInstancetrue

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调用它才能强制执行片段以使其失效,重新分配并且永不重新创建