在应用XML属性之前恢复视图状态

Nic*_*las 8 android android-custom-view android-xml android-savedstate

我有一个自定义视图,让我们说这是它的代码:

public class CustomView extends View {

    boolean visible;
    boolean enabled;

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, 0, 0);
        try {
            visible = a.getBoolean(R.styleable.CustomView_visible, true);
            enabled = a.getBoolean(R.styleable.CustomView_enabled, true);
        } finally {
            a.recycle();
        }

        // Apply XML attributes here
    }

    @Override
    public Parcelable onSaveInstanceState() {
        // Save instance state
        Bundle bundle = new Bundle();
        bundle.putParcelable("superState", super.onSaveInstanceState());
        bundle.putBoolean("visible", visible);
        bundle.putBoolean("enabled", enabled);

        return bundle;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        // Restore instance state
        // This is called after constructor
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;
            visible = bundle.getBoolean("visible");
            enabled = bundle.getBoolean("enabled");

            state = bundle.getParcelable("superState");
        }
        super.onRestoreInstanceState(state);
    }
}
Run Code Online (Sandbox Code Playgroud)

非常直截了当.我的自定义视图从XML读取属性并应用它们.在配置更改时保存和恢复这些属性.

但如果我有两种不同的布局,例如两种不同的方向:

[layout-port/view.xml]
<CustomView
    custom:visible="true"
    custom:enabled="true"

[layout-land/view.xml]
<CustomView
    custom:visible="false"
    custom:enabled="false"
Run Code Online (Sandbox Code Playgroud)

我的问题是,在更改设备方向时,视图状态将保存为可见并启用,但现在XML布局声明视图不应具有.在onRestoreInstanceState之前调用构造函数,并且XML属性将被保存的状态覆盖.我不希望这样,XML优先于保存状态.

我做错了什么?解决这个问题的最佳方法是什么?

rom*_*4ek 0

在您的情况下,您必须将当前方向与Parcelable其他属性一起存储,并且仅在恢复方向等于当前方向(即活动被操作系统破坏并恢复)的情况下应用这些恢复的属性。在你的情况下,我将用于android:tag定义当前方向,如下所示:

[layout-port/view.xml]
<CustomView
    android:tag="port"
    custom:visible="true"
    custom:enabled="true"

[layout-land/view.xml]
<CustomView
    android:tag="land"
    custom:visible="false"
    custom:enabled="false"
Run Code Online (Sandbox Code Playgroud)

然后你的自定义视图类将是这样的:

public class ScheduleView extends View {

    String orientation;
    boolean visible;
    boolean enabled;

    public ScheduleView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomView, 0, 0);
        try {
            visible = a.getBoolean(R.styleable.CustomView_visible, true);
            enabled = a.getBoolean(R.styleable.CustomView_enabled, true);
        } finally {
            a.recycle();
        }

        orientation = (String) getTag();
    }

    @Override
    public Parcelable onSaveInstanceState() {
        // Save instance state
        Bundle bundle = new Bundle();
        bundle.putParcelable("superState", super.onSaveInstanceState());
        bundle.putBoolean("visible", visible);
        bundle.putBoolean("enabled", enabled);
        bundle.putString("orientation", orientation);

        return bundle;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        // Restore instance state
        // This is called after constructor
        if (state instanceof Bundle) {
            Bundle bundle = (Bundle) state;

            String restoredOrientation = bundle.getString("orientation");
            if (restoredOrientation.equals(orientation)) {
                visible = bundle.getBoolean("visible");
                enabled = bundle.getBoolean("enabled");
            }

            state = bundle.getParcelable("superState");
        }
        super.onRestoreInstanceState(state);
    }
}
Run Code Online (Sandbox Code Playgroud)

还没有正确测试过,但它应该可以工作。希望它会有所帮助。