安卓自定义组合视图保存和恢复状态无效

3

已解决...

我有一个复合视图,其中包含一些其他控件。我试图覆盖保存onSaveInstanceStateonRestoreInstanceState,但得到了奇怪的结果。

onRestoreInstanceStateParcelable state参数不是我的自定义子类BaseSavedStateSavedState,而且总是BaseSavedState.EMPTY_STATE。(请查找下面的"always fails"代码注释...)

问题似乎很可能出在保存部分,因为在onSaveInstanceState进入后没有调用SavedState.writeToParcel。就好像调用onSaveInstanceState的人在将结果持久化到Parcel之前将其丢弃。

如果有区别,这个视图是在一个片段中托管的。

有任何想法吗?

这是我的类定义:

public class AddressInput extends FrameLayout

这是我的onSaveInstanceStateonRestoreInstanceState代码:

@Override
protected Parcelable onSaveInstanceState()
{
    // Return saved state
    Parcelable superState = super.onSaveInstanceState();
    return new AddressInput.SavedState( superState, mCurrentLookUp );
}

@Override
protected void onRestoreInstanceState( Parcelable state )
{
    // **** (state == BaseSavedState.EMPTY_STATE) is also always true 

    // Cast state to saved state
    if ( state instance of AddressInput.SavedState )     // **** <---  always fails
    {
        AddressInput.SavedState restoreState = (AddressInput.SavedState)state;

        // Call super with its portion
        super.onRestoreInstanceState( restoreState.getSuperState() );

        // Get current lookup
        mCurrentLookUp = restoreState.getCurrentLookup();
    }
    else
        // Just send to super
        super.onRestoreInstanceState( state );
}

以下是我定制的BaseSavedState子类(AddressInput的内部类):

public static class SavedState extends BaseSavedState
{
    private String mCurrentLookup;

    public SavedState(Parcelable superState, String currentLookup)
    {
        super(superState);
        mCurrentLookup = currentLookup;
    }

    private SavedState(Parcel in)
    {
        super(in);
        this.mCurrentLookup = in.readString();
    }

    public String getCurrentLookup()
    {
        return mCurrentLookup;
    }

    @Override
    public void writeToParcel(Parcel out, int flags)
    {
        super.writeToParcel(out, flags);
        out.writeString( this.mCurrentLookup );
    }

    public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>()
    {
        public AddressInput.SavedState createFromParcel(Parcel in)
        {
            return new AddressInput.SavedState(in);
        }

        public AddressInput.SavedState[] newArray(int size) {
            return new AddressInput.SavedState[size];
        }
    };
}

如果有关系的话,由于onSaveInstanceStateonRestoreInstanceState都被调用了,因此视图在片段布局中确实分配了一个id - DaveOddy
2个回答

6
找到答案了...我的自定义视图中,FrameLayout 的 ID 与特定实例的自定义视图使用的 ID 相同。状态被实例正确保存,然后被没有要保留状态的 FrameLayout 覆盖(清除)。
我还将其基类更改为 RelativeView,这更有意义。
在自定义视图的 XML 中:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp"
            android:id="@+id/addressInput"
            android:background="@drawable/rounded_edit">

实例用法:

    <com.myStuff.AddressInput
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:id="@+id/addressInput"
            android:layout_marginTop="10dp"
            app:addressMode="Domestic"
            app:showSelect="true"
            app:showClear="true" />

改为:(@+id/addressInput -> @+id/shippingAddress)
    <com.myStuff.AddressInput
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            android:id="@+id/shippingAddress"
            android:layout_marginTop="10dp"
            app:addressMode="Domestic"
            app:showSelect="true"
            app:showClear="true" />

让你希望有一些作用域限制来防止这种情况发生。为什么你要知道自定义视图的内部才能确保避免ID冲突呢?

2
很高兴看到您解决了问题。
关于您的自定义组合视图问题,我认为可以对自定义视图的XML文件进行改进:
使用“merge”标记作为根元素,而不是任何实际的布局标记(例如:RelativeLayout)。
这将防止视图冗余,如此博客中所描述的那样。此外,您无需为自定义视图分配任何ID,因此可以避免ID冲突。
很抱歉我没有足够的声誉添加评论,所以我写了另一篇文章。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接