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

2023-09-05 06:03:42 作者:夢已醒心已傷

假设你想从现有的视图实现派生自己的视图类,平添几分价值,因此维持其重新present你查看的状态,以一种有意义的方式几个变量。

Assume you want to derive your own View class from an existing View implementation, adding a bit of value, hence maintaining a few variables which represent your View's state in a meaningful way.

这将是很好,如果你查看​​将保存其状态自动就像其他人(如果一个ID分配),所以你将要覆盖 onRestoreInstanceState()的onSaveInstanceState()

It would be nice if your View would save its state automatically just like others do (if an ID is assigned) so you would want to override onRestoreInstanceState() and onSaveInstanceState().

当然,你需要调用你的基类的相应方法,你需要你的状态信息与你的基类的组合。

Of course, you need to call the respective methods of your base class, and you need to combine your state information with that of your base class.

显然,唯一安全的方法,这样做是包装在自己的超类 Parcelable Parcelable 这样的按键不会弄混。

Obviously, the only safe way to do so is to wrap your super class' Parcelable in an own Parcelable such that the keys won't get mixed up.

现在有View.BaseSavedState其有趣的 getSuperState()方法,但我有点不明白这到底有多增加价值,只是存储基类的 Parcelable 捆绑连同派生视图的状态值并返回。在另一方面,也许一些其他系统组件将期望所有InstanceState信息是类型 View.AbsSavedState (例如,使得 getSuperState()可调用)?

Now there's View.BaseSavedState and its interesting getSuperState() method but I somehow fail to understand how this really adds value to just storing the base class' Parcelable in a Bundle along with the derived View's state values and return that. On the other hand, maybe some other system component will expect all InstanceState information to be of type View.AbsSavedState (e.g. such that getSuperState() can be called)?

你愿意分享任何经验?

推荐答案

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

I think the design needs us, and as the name implies, to implement a subclass of View.BaseSavedState to store values by overriding Parcelable's interface.

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

TextView.SavedState is a good example

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);
        }
    }
}