动态删除片段并保存其UI转换

时间:2012-12-29 07:48:23

标签: android android-fragments

我有几个片段可以替代另一个片段。这些片段的UI发生了变化,我需要保持它的新状态。因此代码看起来非常简单:

    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager
            .beginTransaction();

    if (mStepTwo == null) {
        mStepTwo = new QuizStepTwo();
        mStepTwo.setListener(mStepTwoListener);
    } else {
        fragmentTransaction.remove(mStepTwo);
    }

    fragmentTransaction.replace(R.id.step_holder, mStepTwo);
    fragmentTransaction.addToBackStack("second_step");

    fragmentTransaction.commit();

然而,当我用第一步替换第二步时,例如按下后退按钮, - 它的'UI状态回滚到初始状态。

我如何保持国家? OnSaveInstanceState?还是更舒服的东西?

类似问题:Android Fragment view state within a tab hostHow to restore Android fragment view state

5 个答案:

答案 0 :(得分:3)

我没有用过这个,所以里程可能会有所不同。替换片段时可以尝试使用FragmentManager.saveFragmentInstanceState方法,然后在恢复片段时使用Fragment.setInitialSavedState方法。从文档中可以看出,它只有在制作相同类型的新片段时才有效,因此不确定这是否适用于您当前的实现。

答案 1 :(得分:2)

This question (and its solution)看起来与您尝试的相似。

然而,我能想到的一个替代解决方案是用第二个片段替换第一个片段而是隐藏它(用fragmentTransaction.hide()),或者分离。这样,当用户按下BACK时,将显示片段并且其状态将保持不变。它可能需要更多的内存,但它仍然可以工作,因为片段不会被破坏。

答案 2 :(得分:1)

如果状态取决于您的应用数据,最好将它们保存在SharedPreferences文件中并使用它来构建UI元素。

答案 3 :(得分:1)

查看Fragment documentation example

您可以使用onSaveInstanceState方法存储您的状态

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt("curChoice", mCurCheckPosition);
}

然后在onActivityCreated回调

上检索它
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if (savedInstanceState != null) {
        // Restore last state for Fragment documentation examplechecked position.
        mCurCheckPosition = savedInstanceState.getInt("curChoice", 0);
    }
}

答案 4 :(得分:0)

添加和替换之间的区别是当我们添加前一个片段时没有暂停或停止。当我们尝试替换片段时,前一个片段经历一个暂停和停止的循环。 但是当我们把它放在堆栈中时,前一个片段保存在堆栈顶部。并在诸如背压等事件中检索并加载。

因此,如果您的解决方案需要您的UI永远不会被停止或卸载,您应该隐藏它并在其上添加一个片段。 或者,如果可以卸载片段,则可以使用某种类型的参数重新生成UI。所以你可以在片段内存中有一些参数来确定它应该保存的统计数据。默认情况下,它会尝试保持一些默认状态。但是休息时你可以创建你的对象并将其附加到片段。

对于onSaveInstanceState,它将在包含片段的活动被关闭时调用,即主页按下等事件。

e.g

public class MainActivityFragment1 extends Fragment {
    int alreadyCreated = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        if (alreadyCreated == 1) { // restoreLayout();
            Log.i("MainActivity", " Fragment already created and can be restored Fragment 1");
        }else
            Log.i("MainActivity", " Running Once Fragment 1");

        alreadyCreated = 1;


    01-07 16:08:07.009: I/MainActivity(14722):  Running Once Fragment 1
    01-07 16:08:09.239: I/MainActivity(14722):  MainActivity I on pause
    01-07 16:08:09.239: I/MainActivity(14722):  MainActivity I on stop
    01-07 16:08:09.239: I/MainActivity(14722):  Running Once Fragment 2
    01-07 16:08:13.499: I/MainActivity(14722):  Back Pressed
    01-07 16:08:13.619: I/MainActivity(14722):  MainActivity II on pause
    01-07 16:08:13.619: I/MainActivity(14722):  MainActivity II on stop

01-07 16:08:13.619: I/MainActivity(14722):  MainActivity II on stop
01-07 16:08:13.619: I/MainActivity(14722):  MainActivity II on stop
01-07 16:08:13.619: I/MainActivity(14722):  Fragment already created and can be restored Fragment 1