屏幕旋转时保留多个碎片

时间:2016-11-16 15:40:12

标签: android android-fragments

首先,我知道我可以使用setRetainInstance(true);保留一个片段,并在FragmentManager时从savedInstanceState检索。

但我的情况是我的Activity中有三个片段,我使用事务“交换”,具体取决于用户操作。 我还可以重新创建当前片段,将标志保存在onSaveInstanceState(Bundle savedInstanceState)内,以便在用户旋转屏幕时恢复它。

我的问题出现在用户旋转屏幕时,在一个片段中,然后单击以转到上一个片段。由于我可以恢复的唯一片段是活动片段,因此我无法在不重新分析它的情况下显示前一个片段(丢失了我所拥有的所有信息)。

这是我的代码。如果这不是一个好的解决方案,我会提供任何提示。

private Fragment1 fragment1;
private Fragment2 fragment2;
private Fragment3 fragment3;
private String currentFragmentTAG;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_weight);

    ...

    mFragmentManager = getSupportFragmentManager();

    if (savedInstanceState != null) {
        // HOW TO RECOVER ALL FRAGMENTS??
        fragment1 = ??;
        fragment2 = ??;
        fragment3 = ??;

        String tag = savedInstanceState.getString(SAVED_FRAGMENT);
        Fragment savedFragment = mFragmentManager.findFragmentByTag(tag);
        replaceFragment(savedFragment, tag, null);
    }
}

// Here, in other funcions, I initialize fragments and show one of them depending of user actions
// I use replaceFragment function to "swap" fragments.

private void replaceFragment(Fragment fragment, String tag, Map<String, Parcelable> objectsToBundle) {
    if (fragment != null && !tag.equals(currentFragmentTAG)) {
        FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();

        if (objectsToBundle != null && !objectsToBundle.isEmpty()) {
            Bundle bundle = new Bundle();

            for (Map.Entry<String, Parcelable> entry : objectsToBundle.entrySet()) {
                bundle.putParcelable(entry.getKey(), entry.getValue());
            }

            fragment.setArguments(bundle);
        }

        mFragmentTransaction.replace(R.id.fragment_weight_container, fragment, tag);
        mFragmentTransaction.commit();

        currentFragmentTAG = tag;
    }
}

在我的片段中,我使用setRetainInstance(true)

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // retain this fragment
    setRetainInstance(true);
}

非常感谢你!

1 个答案:

答案 0 :(得分:0)

解决方案非常简单。我只需要在FragmentTransaction.addToBackStack(tag)函数中执行事务时使用replaceFragment。这样,我的活动中使用的所有片段都将保留,并且可以从FragmentManager

中恢复
...
FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
mFragmentTransaction.addToBackStack(tag);
...

所以这就是我可以恢复它们的方式(如果已经实例化的话)

if (savedInstanceState != null) {
    mWeightMainFragment = (WeightMainFragment) mFragmentManager.findFragmentByTag(WeightMainFragment.TAG);
    mWeightAddFragment = (WeightAddFragment) mFragmentManager.findFragmentByTag(WeightAddFragment.TAG);
    mWeightChartFragment = (WeightChartFragment) mFragmentManager.findFragmentByTag(WeightChartFragment.TAG);

    currentFragmentTAG = savedInstanceState.getString(SAVED_FRAGMENT);
    Fragment savedFragment = mFragmentManager.findFragmentByTag(currentFragmentTAG);
    replaceFragment(savedFragment, currentFragmentTAG, null);
}
  

奖励:我还使用popBackStack()撤消转码,而不是使用后台堆栈片段再次替换。