我在SO上找到很多类似的问题,但是没有答案符合我的要求。
我有不同的纵向和横向布局,并且我正在使用返回栈,这两个因素都防止我使用setRetainState()
和配置更改程序的技巧。
我在TextView中向用户展示 certain information,它们不会在默认处理程序中保存。当只使用Activities编写我的应用程序时,以下方法效果良好:
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));
}
对于Fragment
,这仅在非常特定的情况下有效。具体而言,在替换片段、将其放入后退堆栈并在显示新片段时旋转屏幕时会出现严重问题。据我所知,当被替换时,旧片段不会收到调用onSaveInstanceState()
的通知,但仍然与Activity
相关联,当其View
不存在时稍后才调用此方法,因此查找任何TextView
都会导致NullPointerException
。
此外,我发现即使在Activity
中是可以的,在Fragment
中保留对我的TextViews
的引用也不是一个好主意。在这种情况下,onSaveInstanceState()
实际上保存了状态,但如果我在片段隐藏时旋转屏幕两次,则问题会重新出现,因为它的onCreateView()
在新实例中没有被调用。
我考虑在onDestroyView()
中将状态保存到某个Bundle
类型的类成员元素中(实际上是更多数据,而不只是一个TextView
),并在onSaveInstanceState()
中保存那个,但还有其他缺点。主要是,如果当前正在显示片段,则两个函数的调用顺序会颠倒,因此我需要考虑两种不同的情况。一定有更简洁和正确的解决方案!
getFragment()
返回的结果进行强制类型转换,例如mContent = (ContentFragment)getSupportFragmentManager().getFragment(savedInstanceState, "mContent");
。 - ross studtman