Android自定义复合视图保存和恢复状态不起作用

时间:2013-12-05 12:25:53

标签: android state android-custom-view custom-view onrestoreinstancestate

...解决

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

Parcelable state的{​​{1}}参数不属于onRestoreInstanceStateBaseSavedState的自定义子类,并且似乎始终为SavedState。 (在下面查找“总是失败”代码评论......

似乎问题可能在于保存部分,因为在BaseSavedState.EMPTY_STATE之后没有调用SavedState.writeToParcel几乎就好像正在调用onSaveInstanceState enters.的人在持久化之前抛出结果它到onSaveInstanceState

如果它有所不同,则此视图托管在片段中。

有什么想法吗?

以下是我的班级定义:

Parcel

以下是我的public class AddressInput extends FrameLayout onSaveInstanceState对:

onRestoreInstanceState

这是我的自定义@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

2 个答案:

答案 0 :(得分: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 - &gt; @ + 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来防止这种事情。为什么您必须了解自定义视图的内部结构以确保避免ID冲突?

答案 1 :(得分:2)

很高兴看到你解决了这个问题。

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

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

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

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