系统如何自动保留ListView滚动位置?
您可能已经注意到,即使您没有处理onSaveInstanceState
方法,某些数据在旋转期间也不会受到影响。例如:
- EditText中的滚动位置文本
- EditText中的文本等。
屏幕旋转时会发生什么?
当屏幕旋转时,系统会杀死活动的实例并重新创建一个新实例。系统这样做是为了为不同的配置提供最合适的资源给活动。当完整的活动进入多面板屏幕时,也会发生同样的事情。
系统如何重新创建新实例?
系统使用活动实例的旧状态来创建一个新实例,称为“实例状态”。实例状态是存储在Bundle
对象中的键值对集合。
默认情况下,系统会将View对象保存在Bundle中,例如:滚动位置EditText等。
因此,如果您想保存应该在方向更改后继续存在的其他数据,则应覆盖onSaveInstanceState(Bundle saveInstanceState)
方法。
在覆盖onSaveInstance方法时要小心!!!
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt(STATE_SCORE, mCurrentScore);
super.onSaveInstanceState(savedInstanceState);
}
始终调用super.onSaveInstanceState(savedInstanceState)
,否则默认行为将无法正常工作。例如,在方向更改期间EditText的值将不会持久保存。不相信我吗?请查看此代码。
恢复数据时使用哪种方法?
onCreate(Bundle savedInstanceState)
还是
onRestoreInstanceState(Bundle savedInstanceState)
这两种方法都获取相同的Bundle对象,因此在哪里编写恢复逻辑并不重要。唯一的区别是,在onCreate(Bundle savedInstanceState)
方法中,您将需要进行空值检查,而在后一种情况下则不需要。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = (TextView) findViewById(R.id.main);
if (savedInstanceState != null) {
CharSequence savedText = savedInstanceState.getCharSequence(KEY_TEXT_VALUE);
mTextView.setText(savedText);
}
}
OR
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
mCurrentScore = savedInstanceState.getInt(STATE_SCORE);
}
始终调用
super.onRestoreInstanceState(savedInstanceState)
,以便系统默认恢复视图层次结构。