我在SO上发现了许多类似问题的实例,但不幸的是,没有答案符合我的要求。
我对人像和风景有不同的布局,并且我使用的是后向堆栈,这既妨碍了我的使用,又使我无法setRetainState()使用配置更改例程。
setRetainState()
我在TextViews中向用户显示某些信息,这些信息不会保存在默认处理程序中。当仅使用“活动”编写我的应用程序时,以下方法运行良好:
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)); }
使用Fragments,这仅在非常特殊的情况下有效。具体地说,令人震惊的是替换片段,将其放回堆栈中,然后在显示新片段时旋转屏幕。据我了解,旧片段onSaveInstanceState()在被替换时不会收到调用,而是以某种方式保持链接,Activity并且当该方法View不再存在时将调用此方法,因此将我TextView的任何结果都查找到中NullPointerException。
Fragments
onSaveInstanceState()
Activity
TextView
NullPointerException
另外,我发现即使TextViews使用Fragments也可以,但Activity对s保持引用不是一个好主意。在那种情况下,onSaveInstanceState()实际上可以保存状态,但是如果在隐藏片段时旋转屏幕两次,问题就会再次出现,因为onCreateView()在新实例中不会调用该片段。
s
onCreateView()
我想到了将状态保存onDestroyView()到某种Bundle-type类成员元素中(实际上是更多数据,而不仅仅是一个TextView),并将其保存到其中,onSaveInstanceState()但是还有其他缺点。首先,如果该片段是当前显示,调用两个函数的顺序是相反的,所以我需要考虑两种不同的情况。必须有一个更清洁,正确的解决方案!
onDestroyView()
Bundle-type
要正确保存实例状态,Fragment请执行以下操作:
1.在片段中,通过覆盖保存实例状态onSaveInstanceState()并在中还原onActivityCreated():
onActivityCreated()
class MyFragment extends Fragment { @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 } }
2.而且很重要的一点,在活动中,你必须保存片段的实例在onSaveInstanceState()和恢复onCreate()。
onCreate()
class MyActivity extends Activity { private MyFragment public void onCreate(Bundle savedInstanceState) { ... if (savedInstanceState != null) { //Restore the fragment's instance mMyFragment = getSupportFragmentManager().getFragment(savedInstanceState, "myFragmentName"); ... } ... } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); //Save the fragment's instance getSupportFragmentManager().putFragment(outState, "myFragmentName", mMyFragment); } }
希望这可以帮助。