Не работает пользовательское составное представление 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) в качестве корневого элемента.
Это предотвратит избыточность представления, как описано в этом блоге. Также вам не нужно присваивать какой-либо идентификатор пользовательскому представлению, чтобы избежать конфликта идентификаторов.
Извините, у меня недостаточно репутации, чтобы добавить комментарий, поэтому я пишу еще один пост.