Skip to content

Instantly share code, notes, and snippets.

@hrules6872
Created February 23, 2017 23:01
Show Gist options
  • Save hrules6872/6b7d9e0889a96e58b3aacaf68d7e4cf3 to your computer and use it in GitHub Desktop.
Save hrules6872/6b7d9e0889a96e58b3aacaf68d7e4cf3 to your computer and use it in GitHub Desktop.
Custom Viewgroup: onSaveInstanceState - onRestoreInstanceState http://trickyandroid.com/saving-android-view-state-correctly/
public class CustomLayout extends LinearLayout {
@SuppressWarnings("unchecked") @Override public Parcelable onSaveInstanceState() {
Parcelable saveInstanceState = super.onSaveInstanceState();
SavedState savedState = new SavedState(saveInstanceState);
savedState.childrenStates = new SparseArray();
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).saveHierarchyState(savedState.childrenStates);
}
return savedState;
}
@SuppressWarnings("unchecked") @Override public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState) state;
super.onRestoreInstanceState(savedState.getSuperState());
for (int i = 0; i < getChildCount(); i++) {
getChildAt(i).restoreHierarchyState(savedState.childrenStates);
}
}
@Override protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
dispatchFreezeSelfOnly(container);
}
@Override protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
dispatchThawSelfOnly(container);
}
private static class SavedState extends BaseSavedState {
private SparseArray childrenStates;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in, ClassLoader classLoader) {
super(in);
childrenStates = in.readSparseArray(classLoader);
}
@SuppressWarnings("unchecked") @Override public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeSparseArray(childrenStates);
}
public static final ClassLoaderCreator<SavedState> CREATOR = new ClassLoaderCreator<SavedState>() {
@Override public SavedState createFromParcel(Parcel source, ClassLoader loader) {
return new SavedState(source, loader);
}
@Override public SavedState createFromParcel(Parcel source) {
return createFromParcel(null);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
@ngima
Copy link

ngima commented May 31, 2017

Thanks, I saved my day. 👍

@thekalinga
Copy link

thekalinga commented Aug 17, 2017

For those who use IcePick, you can use this. This does the same thing as above but lil less ceremony

import android.os.Parcel;
import android.os.Parcelable;
import android.util.SparseArray;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import icepick.State;

import static icepick.Icepick.restoreInstanceState;
import static icepick.Icepick.saveInstanceState;

class Util {
  private Util() {}

  public static SparseArray saveChildViewStates(ViewGroup viewGroup) {
    SparseArray childViewStates = new SparseArray();
    for (int i = 0; i < viewGroup.getChildCount(); i++) {
      //noinspection unchecked
      viewGroup.getChildAt(i).saveHierarchyState(childViewStates);
    }
    return childViewStates;
  }

  public static void restoreChildViewStates(ViewGroup viewGroup, SparseArray childViewStates) {
    for (int i = 0; i < viewGroup.getChildCount(); i++) {
      //noinspection unchecked
      viewGroup.getChildAt(i).restoreHierarchyState(childViewStates);
    }
  }
}

public class CustomLayout extends LinearLayout {

  @State
  MyCustomParcellable myInternalState;

  @State
  int additionalState;

  @State
  SparseArray childViewStates;

  @Override
  public Parcelable onSaveInstanceState() {
    childViewStates = Util.saveChildViewStates(this);
    return saveInstanceState(this, super.onSaveInstanceState());
  }

  @Override
  public void onRestoreInstanceState(Parcelable state) {
    super.onRestoreInstanceState(restoreInstanceState(this, state));
    Util.restoreChildViewStates(this, childViewStates);
    childViewStates = null;
  }

  @Override protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {
    dispatchFreezeSelfOnly(container);
  }

  @Override protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {
    dispatchThawSelfOnly(container);
  }

}

class MyCustomParcellable implements Parcelable {
  // lot of properties & parcellable implementation; use android studio extension (Android Parcelable Generator) to generate parcellable implementation
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment