场景:一个Tab中的一个子Activty里有listView
a.如果在此Activty中启动其他应用,当返回时系统为我门保存了当前状态(应该也是调用了以下方法来保存)。
a.如果在此Activty中启动其他应用,当返回时系统为我门保存了当前状态(应该也是调用了以下方法来保存)。
b.如果是在其他子Activty中启动其他应用,当返回时ListView滑动状态就会丢失。
View类有一个继承自AbsSavedState的BaseSavedState类,所有View的子类都会继承这个BaseSavedState类。当然包括ListView,TextView等等。以下代码即可实现场景b中保存ListView滑动状态:
1.写出以下方法
/**
* Used to keep track of the scroll state of the list.
*/
private Parcelable mListState = null;
private static final String LIST_STATE_KEY = "liststate";
@Override
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
// Save list state in the bundle so we can restore it after the QueryHandler has run
if (mList != null) {
icicle.putParcelable(LIST_STATE_KEY, mList.onSaveInstanceState());
}
}
@Override
protected void onRestoreInstanceState(Bundle icicle) {
super.onRestoreInstanceState(icicle);
// Retrieve list state. This will be applied after the QueryHandler has run
mListState = icicle.getParcelable(LIST_STATE_KEY);
}
2.在合适的地方调用(比如onCreate):
if(mListState!=null){
mList.onRestoreInstanceState(mListState);
mListState = null;
}
在ListView中SavedState继承自BaseSavedState,ListView中的实现如下:
static class SavedState extends BaseSavedState {
SparseBooleanArray checkState;
LongSparseArray<Boolean> checkIdState;
/**
* Constructor called from {@link ListView#onSaveInstanceState()}
*/
SavedState(Parcelable superState, SparseBooleanArray checkState,
LongSparseArray<Boolean> checkIdState) {
super(superState);
this.checkState = checkState;
this.checkIdState = checkIdState;
}
/**
* Constructor called from {@link #CREATOR}
*/
private SavedState(Parcel in) {
super(in);
checkState = in.readSparseBooleanArray();
long[] idState = in.createLongArray();
if (idState.length > 0) {
checkIdState = new LongSparseArray<Boolean>();
checkIdState.setValues(idState, Boolean.TRUE);
}
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeSparseBooleanArray(checkState);
out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]);
}
@Override
public String toString() {
return "ListView.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " checkState=" + checkState + "}";
}
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
//以下实现状态的保存和回复
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
return new SavedState(superState, mCheckStates, mCheckedIdStates);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
if (ss.checkState != null) {
mCheckStates = ss.checkState;
}
if (ss.checkIdState != null) {
mCheckedIdStates = ss.checkIdState;
}
}
View中,BaseSaveState的实现如下:
/**
* Base class for derived classes that want to save and restore their own
* state in {@link android.view.View#onSaveInstanceState()}.
*/
public static class BaseSavedState extends AbsSavedState {
/**
* Constructor used when reading from a parcel. Reads the state of the superclass.
*
* @param source
*/
public BaseSavedState(Parcel source) {
super(source);
}
/**
* Constructor called by derived classes when creating their SavedState objects
*
* @param superState The state of the superclass of this view
*/
public BaseSavedState(Parcelable superState) {
super(superState);
}
public static final Parcelable.Creator<BaseSavedState> CREATOR =
new Parcelable.Creator<BaseSavedState>() {
public BaseSavedState createFromParcel(Parcel in) {
return new BaseSavedState(in);
}
public BaseSavedState[] newArray(int size) {
return new BaseSavedState[size];
}
};
}
AbsSavedState类实现了Parcelable接口,具体实现如下:
/**
* A {@link Parcelable} implementation that should be used by inheritance
* hierarchies to ensure the state of all classes along the chain is saved.
*/
public abstract class AbsSavedState implements Parcelable {
public static final AbsSavedState EMPTY_STATE = new AbsSavedState() {};
private final Parcelable mSuperState;
/**
* Constructor used to make the EMPTY_STATE singleton
*/
private AbsSavedState() {
mSuperState = null;
}
/**
* Constructor called by derived classes when creating their SavedState objects
*
* @param superState The state of the superclass of this view
*/
protected AbsSavedState(Parcelable superState) {
if (superState == null) {
throw new IllegalArgumentException("superState must not be null");
}
mSuperState = superState != EMPTY_STATE ? superState : null;
}
/**
* Constructor used when reading from a parcel. Reads the state of the superclass.
*
* @param source
*/
protected AbsSavedState(Parcel source) {
// FIXME need class loader
Parcelable superState = source.readParcelable(null);
mSuperState = superState != null ? superState : EMPTY_STATE;
}
final public Parcelable getSuperState() {
return mSuperState;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(mSuperState, flags);
}
public static final Parcelable.Creator<AbsSavedState> CREATOR
= new Parcelable.Creator<AbsSavedState>() {
public AbsSavedState createFromParcel(Parcel in) {
Parcelable superState = in.readParcelable(null);
if (superState != null) {
throw new IllegalStateException("superState must be null");
}
return EMPTY_STATE;
}
public AbsSavedState[] newArray(int size) {
return new AbsSavedState[size];
}
};
}