As respostas aqui já são ótimas, mas não necessariamente funcionam para grupos de vistas personalizados. Para que todas as Views personalizadas mantenham seu estado, você deve substituir onSaveInstanceState()e onRestoreInstanceState(Parcelable state)em cada classe. Você também precisa garantir que todos tenham IDs exclusivos, sejam inflados a partir do xml ou adicionados programaticamente.
O que eu criei foi notavelmente como a resposta do Kobor42, mas o erro permaneceu porque eu estava adicionando as Views a um ViewGroup personalizado programaticamente e não atribuindo IDs exclusivos.
O link compartilhado por mato funcionará, mas significa que nenhuma das Visualizações individuais gerencia seu próprio estado - todo o estado é salvo nos métodos do ViewGroup.
O problema é que, quando vários desses grupos de vistas são adicionados a um layout, os IDs de seus elementos do xml não são mais exclusivos (se definidos em xml). No tempo de execução, você pode chamar o método estático View.generateViewId()para obter um ID exclusivo para uma Visualização. Isso está disponível apenas na API 17.
Aqui está o meu código do ViewGroup (é abstrato e mOriginalValue é uma variável de tipo):
public abstract class DetailRow<E> extends LinearLayout {
private static final String SUPER_INSTANCE_STATE = "saved_instance_state_parcelable";
private static final String STATE_VIEW_IDS = "state_view_ids";
private static final String STATE_ORIGINAL_VALUE = "state_original_value";
private E mOriginalValue;
private int[] mViewIds;
// ...
@Override
protected Parcelable onSaveInstanceState() {
// Create a bundle to put super parcelable in
Bundle bundle = new Bundle();
bundle.putParcelable(SUPER_INSTANCE_STATE, super.onSaveInstanceState());
// Use abstract method to put mOriginalValue in the bundle;
putValueInTheBundle(mOriginalValue, bundle, STATE_ORIGINAL_VALUE);
// Store mViewIds in the bundle - initialize if necessary.
if (mViewIds == null) {
// We need as many ids as child views
mViewIds = new int[getChildCount()];
for (int i = 0; i < mViewIds.length; i++) {
// generate a unique id for each view
mViewIds[i] = View.generateViewId();
// assign the id to the view at the same index
getChildAt(i).setId(mViewIds[i]);
}
}
bundle.putIntArray(STATE_VIEW_IDS, mViewIds);
// return the bundle
return bundle;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
// We know state is a Bundle:
Bundle bundle = (Bundle) state;
// Get mViewIds out of the bundle
mViewIds = bundle.getIntArray(STATE_VIEW_IDS);
// For each id, assign to the view of same index
if (mViewIds != null) {
for (int i = 0; i < mViewIds.length; i++) {
getChildAt(i).setId(mViewIds[i]);
}
}
// Get mOriginalValue out of the bundle
mOriginalValue = getValueBackOutOfTheBundle(bundle, STATE_ORIGINAL_VALUE);
// get super parcelable back out of the bundle and pass it to
// super.onRestoreInstanceState(Parcelable)
state = bundle.getParcelable(SUPER_INSTANCE_STATE);
super.onRestoreInstanceState(state);
}
}