清理动态添加的片段

时间:2014-09-30 09:25:21

标签: android android-fragments

以下代码已简化,仅显示相关内容。

我有一个布局XML文件:

<LinearLayout
    android:id="@+id/top_row"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"/>

使用Fragment

ViewPager FragmentStatePagerAdapter onCreateView()中夸大此布局

在我们想要动态添加子片段的Fragment的{​​{1}}中,可以是任何类型的数字。所以我们这样做:

View view = inflater.inflate(R.layout.the_layout, container, false);

FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();

for(Fragment f : fragments) {
    transaction.add(R.id.top_row, frag);
}

transaction.commit();

完美地运作,所有碎片很好地彼此相邻排列。

但问题在于:每当再次调用Activity的onCreate时,ViewPager都会设置为新的Adapter。所以我希望一切都能重建。 因此,系统会调用onCreateView,因此会创建一个新的View并将Fragments添加到此新LinearLayout

实际发生的事情是,之前的Fragments似乎仍然存在!新的Fragments会添加到之前添加的Fragments中。所以假设有3个Fragments,在onCreateView()被调用3次后,我有9个。

我认为发生了什么:Fragments与ID View相关联,因此它们也会被添加到新的View中。 我认为我应该做的是:删除Fragments中的所有onDestroyView(),但不允许这样做(在onSaveInstanceState()生成onPause()之后无法生成此内容崩溃)。

这不应该以这种方式完成吗?我应该使用FrameLayout的布局并在这些布局上使用FragmentTransaction.replace()吗?

我的ActivityonCreate()外没有其他功能实现。这里它实例化适配器并将其设置在ViewPager

FragmentStatePagerAdapter本身非常简单,getItem()只返回特定的Fragment

return new MyFragment();

1 个答案:

答案 0 :(得分:5)

  

我认为我应该做的是:删除onDestroyView()

中的所有片段

不要那样做。它不会有任何好处。

不确定您是否知道 - 如果您的Activity重新创建而未事先通过调用finish()或按下后退按钮而被明确销毁 - 则表示restored from previous instance state

在这种情况下,您不应再次执行该事务,因为 - 它已经通过super.onCreate()Activity方法自动发生。事实上,如果你在这种情况下执行片段trasaction - 你将导致相同的片段被添加两次(2个实例)

通过检查onCreate()参数是否为空,您可以知道当前是否已通过恢复实例状态调用savedInstanceState

您没有检查savedInstanceState,也无法执行交易。

如果我是对的,那么以下更改应该解决片段重复问题:

而不是:

FragmentManager fragmentManager = getChildFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();

for(Fragment f : fragments) {
    transaction.add(R.id.top_row, frag);
}

transaction.commit();

写:

 if (savedInstanceState == null) {
    FragmentManager fragmentManager = getChildFragmentManager();
    FragmentTransaction transaction = fragmentManager.beginTransaction();

    for(Fragment f : fragments) {
        transaction.add(R.id.top_row, frag);
    }

    transaction.commit();
}

更多信息 - http://developer.android.com/guide/components/fragments.html