Не работает пользовательское составное представление Android для сохранения и восстановления

Решено...

У меня есть составное представление, которое содержит некоторые другие элементы управления. Я пытаюсь отменить сохранение onSaveInstanceState а также onRestoreInstanceState, но получаю странный результат.

Parcelable state аргумент onRestoreInstanceState не из моего пользовательского подкласса BaseSavedState, 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 ):

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

2 ответа

Решение

Разобрался... Мой пользовательский вид имел тот же идентификатор для своего 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)

    <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" />

Заставляет вас хотеть, чтобы была некоторая область видимости для идентификации, чтобы предотвратить подобные вещи. Почему вы должны знать о внутренностях пользовательского представления, чтобы избежать конфликта идентификаторов?

Рад видеть, что вы решили проблему.

На ваш вопрос о пользовательском композитном представлении, я думаю, что можно было бы улучшить XML-файл пользовательского представления:

используйте тег "слияние", а не любой фактический тег макета (например: RelativeLayout) в качестве корневого элемента.

Это предотвратит избыточность представления, как описано в этом блоге. Также вам не нужно присваивать какой-либо идентификатор пользовательскому представлению, чтобы избежать конфликта идентификаторов.

Извините, у меня недостаточно репутации, чтобы добавить комментарий, поэтому я пишу еще один пост.

Другие вопросы по тегам