Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/220.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android自定义复合视图保存和还原状态不工作_Android_State_Android Custom View_Custom View_Onrestoreinstancestate - Fatal编程技术网

Android自定义复合视图保存和还原状态不工作

Android自定义复合视图保存和还原状态不工作,android,state,android-custom-view,custom-view,onrestoreinstancestate,Android,State,Android Custom View,Custom View,Onrestoreinstancestate,解决了 我有一个包含一些其他控件的复合视图。我试图覆盖SaveInstanceState上的save和RestoreInstanceState上的save但是得到了一个奇怪的结果 onRestoreInstanceState的Parcelable state参数不属于我的BaseSavedState,SavedState的自定义子类,并且似乎总是BaseSavedState.EMPTY_state。(请在下面查找“始终失败”代码注释 似乎问题可能出在保存部分,因为在onSaveInstanceS

解决了

我有一个包含一些其他控件的复合视图。我试图覆盖SaveInstanceState上的save
和RestoreInstanceState上的save
但是得到了一个奇怪的结果

onRestoreInstanceState
Parcelable state
参数不属于我的
BaseSavedState
SavedState
的自定义子类,并且似乎总是
BaseSavedState.EMPTY_state
。(请在下面查找“始终失败”代码注释

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

如果有区别的话,该视图将托管在片段中

有什么想法吗

这是我的类定义:

public class AddressInput extends FrameLayout
@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 );
}
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];
        }
    };
}
这是我的
onSaveInstanceState
onRestoreInstanceState
对:

public class AddressInput extends FrameLayout
@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 );
}
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];
        }
    };
}

找到了…我的自定义视图的
FrameLayout
ID与用于自定义视图特定实例的ID相同。该实例正确保存了状态,然后被
FrameLayout
覆盖(清除),而该
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)



使您希望对ID进行一些范围限定以防止此类情况发生。为什么您必须了解自定义视图的内部结构以确保避免ID冲突?

很高兴看到您解决了此问题

对于有关自定义复合视图的问题,我认为可以对自定义视图的XML文件进行改进:

使用“merge”标记,而不是任何实际的布局标记(例如:RelativeLayout)作为根元素

这将防止视图冗余,如中所述。此外,您不需要为自定义视图分配任何id,因此可以避免id冲突


很抱歉,我没有足够的声誉来添加评论,所以我写了另一篇文章。

如果有问题,因为肯定会调用
onSaveInstanceState
onRestoreInstanceState
,因此在片段布局中,视图确实分配了一个
id