Пользовательский составной режим просмотра и восстановления пользовательских композиций Android не работает

Решено …

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

Parcelable state для onRestoreInstanceState не относится к моему пользовательскому подклассу BaseSavedState , SavedState и всегда выглядит как BaseSavedState.EMPTY_STATE . (Посмотрите на комментарий коллайдера «всегда не удается» ниже …

Похоже, что проблема SavedState.writeToParcel с частью сохранения, так как SavedState.writeToParcel не onSaveInstanceState enters. после 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 класса 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]; } }; } 

    Выяснилось … Мой пользовательский вид имел тот же 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)

      <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?

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

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

    Используйте тег «merge», а не какой-либо фактический тег макета (например, RelativeLayout) в качестве корневого элемента.

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

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