一劳永逸,如何正确保存回堆碎片的实例状态? [英] Once for all, how to correctly save instance state of Fragments in back stack?

查看:128
本文介绍了一劳永逸,如何正确保存回堆碎片的实例状态?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经找到了一个类似的问题很多情况下对SO,但没有答案不幸的是符合我的要求。

I have found many instances of a similar question on SO but no answer unfortunately meets my requirements.

我有不同的布局为纵向和横向,我使用回栈,既$ P $使用pvents我 setRetainState()和使用配置更改程序的技巧。

I have different layouts for portrait and landscape and I am using back stack, which both prevents me from using setRetainState() and tricks using configuration change routines.

我展示的某些信息到TextViews用户,不被保存在默认的处理程序。当写我的应用程序中使用单独的活动,以下行之有效:

I show certain information to the user in TextViews, which do not get saved in the default handler. When writing my application solely using Activities, the following worked well:

TextView vstup;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.whatever);
    vstup = (TextView)findViewById(R.id.whatever);
    /* (...) */
}

@Override
public void onSaveInstanceState(Bundle state) {
    super.onSaveInstanceState(state);
    state.putCharSequence(App.VSTUP, vstup.getText());
}

@Override
public void onRestoreInstanceState(Bundle state) {
    super.onRestoreInstanceState(state);
    vstup.setText(state.getCharSequence(App.VSTUP));
}

使用片段 S,这只有在非常特殊的情况。具体而言,有什么可怕的破坏是更换一个片段,把它在后面堆栈中,然后旋转屏幕,同时新的片段显示。据我了解,老片段不接听电话,以的onSaveInstanceState()被取代,但保持某种方式联系到活动时,这种方法后来被称为当其查看不存在了,所以找我的任何的TextView 小号结果成 NullPointerException异常

With Fragments, this works only in very specific situations. Specifically, what breaks horribly is replacing a fragment, putting it in the back stack and then rotating the screen while the new fragment is shown. From what I understood, the old fragment does not receive a call to onSaveInstanceState() when being replaced but stays somehow linked to the Activity and this method is called later when its View does not exist anymore, so looking for any of my TextViews results into a NullPointerException.

另外,我发现,保持引用到我的 TextViews 是不符合片段是个好主意,甚至如果它是确定与活动的。在这种情况下,的onSaveInstanceState()实际保存状态,但问题再次出现,如果我旋转屏幕的两次的时候,片段将被隐藏,其 onCreateView()不会被调用的新实例。

Also, I found that keeping the reference to my TextViews is not a good idea with Fragments, even if it was OK with Activity's. In that case, onSaveInstanceState() actually saves the state but the problem reappears if I rotate the screen twice when the fragment is hidden, as its onCreateView() does not get called in the new instance.

我想节省 onDestroyView状态()的进入一些捆绑型的类成员的元素(它实际上更多的数据,而不仅仅是一个的TextView )和保存的的在的onSaveInstanceState()但有其他缺点。首先,如果碎片的的当前显示,调用两个函数的顺序是相反的,所以我需要考虑两种不同的情况。必须有一个更清洁,正确的解决方案!

I thought of saving the state in onDestroyView() into some Bundle-type class member element (it's actually more data, not just one TextView) and saving that in onSaveInstanceState() but there are other drawbacks. Primarily, if the fragment is currently shown, the order of calling the two functions is reversed, so I'd need to account for two different situations. There must be a cleaner and correct solution!

推荐答案

要正确保存片段的实例状态,你应该做以下codeS:

To correctly save instance state of Fragment, you should do following codes:

  1. 在片段,保存实例状态所覆盖的onSaveInstanceState和onActivityCreated恢复:

  1. In the fragment, save instance state by override onSaveInstanceState and restore on onActivityCreated:


@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    ...
    if (savedInstanceState != null) {
        //Restore the fragment's state here
    }
}
...
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

//Save the fragment's state here

}

  • 重要的一点,在活动中,你必须拯救片段的实例上的onSaveInstanceState和的onCreate恢复。

  • And important point, in the activity, you have to save fragment's instance on onSaveInstanceState and restore on onCreate.

    
    public void onCreate(Bundle savedInstanceState) {
        ...
        if (savedInstanceState != null) {
            //Restore the fragment's instance
            mContent = getSupportFragmentManager().getFragment(
                        savedInstanceState, "mContent");
            ...
        }
        ...
    }
    
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    
    
    //Save the fragment's instance
    getSupportFragmentManager().putFragment(outState, "mContent", mContent);
    

    }

  • 希望这有助于。

    这篇关于一劳永逸,如何正确保存回堆碎片的实例状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆