使用 View.BaseSavedState 覆盖 View.onSaveInstanceState() 和 View.onRestoreInstanceState()? [英] Overriding View.onSaveInstanceState() and View.onRestoreInstanceState() using View.BaseSavedState?

查看:29
本文介绍了使用 View.BaseSavedState 覆盖 View.onSaveInstanceState() 和 View.onRestoreInstanceState()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您想从现有的 View 实现派生自己的 View 类,添加一些值,从而维护一些以有意义的方式代表您的 View 状态的变量.

如果您的 View 能像其他人一样自动保存其状态(如果分配了 ID),那么您会想要覆盖 onRestoreInstanceState()onSaveInstanceState().

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

显然,唯一安全的方法是将超类的 Parcelable 包装在自己的 Parcelable 中,这样密钥就不会混淆.

现在有 View.BaseSavedState 及其有趣的getSuperState() 方法,但我不知何故无法理解这如何真正为仅将基类的 ParcelableBundle 一起存储增加价值派生视图的状态值并返回.另一方面,也许其他一些系统组件会期望所有 InstanceState 信息都属于 View.AbsSavedState 类型(例如,可以调用 getSuperState())?

您有什么经验愿意分享吗?

解决方案

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

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

public static class SavedState extends BaseSavedState {int selStart;国际销售;字符序列文本;布尔型frozenWithFocus;字符序列错误;SavedState(Parcelable superState) {超级(超级状态);}@覆盖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);如果(错误==空){out.writeInt(0);} 别的 {out.writeInt(1);TextUtils.writeToParcel(error, out, flags);}}@覆盖公共字符串 toString() {String str = "TextView.SavedState{"+ Integer.toHexString(System.identityHashCode(this))+开始="+selStart+结束="+selEnd;如果(文本!= null){str += " text=" + text;}返回 str + "}";}@SuppressWarnings("隐藏")public static final Parcelable.Creator创造者= new Parcelable.Creator() {public SavedState createFromParcel(Parcel in) {返回新的 SavedState(in);}public SavedState[] newArray(int size) {返回新的 SavedState[size];}};私人保存状态(包裹在){超级(在);selStart = in.readInt();selEnd = in.readInt();frozenWithFocus = (in.readInt() != 0);text = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);如果(in.readInt()!= 0){错误 = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);}}}

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.

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.

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.

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)?

Any experiences you're willing to share?

解决方案

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

这篇关于使用 View.BaseSavedState 覆盖 View.onSaveInstanceState() 和 View.onRestoreInstanceState()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆