使用View.BaseSavedState重写View.onSaveInstanceState()和View.onRestoreInstanceState()?

假设你想从现有的View实现派生你自己的View类,添加一些值,从而以一种有意义的方式保留一些代表View的状态的variables。

如果你的View像其他人那样自动保存它的状态(如果指定了一个ID),那么你会希望重写onRestoreInstanceState()onSaveInstanceState()

当然,你需要调用你的基类的相应方法,并且你需要把你的状态信息和基类的状态信息结合起来。

显然,唯一安全的方法就是将你的超类“ Parcelable ”封装在自己的Parcelable这样密钥就不会混淆了。

现在有View.BaseSavedState和它有趣的getSuperState()方法,但我不知道如何真正增加价值只是存储基类“ Parcelable在一个Bundle与派生视图的状态值并返回。 另一方面,也许一些其他的系统组件会期望所有InstanceState信息的typesView.AbsSavedState (例如,可以调用getSuperState() )?

你愿意分享的任何经验?

Solutions Collecting From Web of "使用View.BaseSavedState重写View.onSaveInstanceState()和View.onRestoreInstanceState()?"

我认为devise需要我们,顾名思义,通过覆盖Parcelable的接口来实现View.BaseSavedState的子类来存储值。

TextView.SavedState就是一个很好的例子

 public static class SavedState extends BaseSavedState { int selStart; int selEnd; CharSequence text; boolean frozenWithFocus; CharSequence error; SavedState(Parcelable superState) { super(superState); } @Override public void writeToParcel(Parcel out, int flags) { super.writeToParcel(out, flags); out.writeInt(selStart); out.writeInt(selEnd); out.writeInt(frozenWithFocus ? 1 : 0); TextUtils.writeToParcel(text, out, flags); if (error == null) { out.writeInt(0); } else { out.writeInt(1); TextUtils.writeToParcel(error, out, flags); } } @Override public String toString() { String str = "TextView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) + " start=" + selStart + " end=" + selEnd; if (text != null) { str += " text=" + text; } return str + "}"; } @SuppressWarnings("hiding") 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]; } }; private SavedState(Parcel in) { super(in); selStart = in.readInt(); selEnd = in.readInt(); frozenWithFocus = (in.readInt() != 0); text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); if (in.readInt() != 0) { error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); } } } 

为了补充James Chen的回答,下面是Charles Harley博客文章中如何使用这个方法的完整例子。

来自链接的代码:

 public class LockCombinationPicker extends LinearLayout { private NumberPicker numberPicker1; private NumberPicker numberPicker2; private NumberPicker numberPicker3; public LockCombinationPicker(Context context) { this(context, null); } public LockCombinationPicker(Context context, AttributeSet attrs) { this(context, attrs, 0); } public LockCombinationPicker(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); loadViews(); } private void loadViews() { LayoutInflater.from(getContext()).inflate(R.layout.lock_combination_picker, this, true); numberPicker1 = (NumberPicker) findViewById(R.id.number1); numberPicker1.setMinValue(0); numberPicker1.setMaxValue(10); numberPicker2 = (NumberPicker) findViewById(R.id.number2); numberPicker2.setMinValue(0); numberPicker2.setMaxValue(10); numberPicker3 = (NumberPicker) findViewById(R.id.number3); numberPicker3.setMinValue(0); numberPicker3.setMaxValue(10); } @Override protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); return new SavedState(superState, numberPicker1.getValue(), numberPicker2.getValue(), numberPicker3.getValue()); } @Override protected void onRestoreInstanceState(Parcelable state) { SavedState savedState = (SavedState) state; super.onRestoreInstanceState(savedState.getSuperState()); numberPicker1.setValue(savedState.getNumber1()); numberPicker2.setValue(savedState.getNumber2()); numberPicker3.setValue(savedState.getNumber3()); } @Override protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) { // As we save our own instance state, ensure our children don't save and restore their state as well. super.dispatchFreezeSelfOnly(container); } @Override protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) { /** See comment in {@link #dispatchSaveInstanceState(android.util.SparseArray)} */ super.dispatchThawSelfOnly(container); } /** * Convenience class to save / restore the lock combination picker state. Looks clumsy but once created is easy to maintain and use. */ protected static class SavedState extends BaseSavedState { private final int number1; private final int number2; private final int number3; private SavedState(Parcelable superState, int number1, int number2, int number3) { super(superState); this.number1 = number1; this.number2 = number2; this.number3 = number3; } private SavedState(Parcel in) { super(in); number1 = in.readInt(); number2 = in.readInt(); number3 = in.readInt(); } public int getNumber1() { return number1; } public int getNumber2() { return number2; } public int getNumber3() { return number3; } @Override public void writeToParcel(Parcel destination, int flags) { super.writeToParcel(destination, flags); destination.writeInt(number1); destination.writeInt(number2); destination.writeInt(number3); } public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; } }