Les réponses ici sont déjà excellentes, mais ne fonctionnent pas nécessairement pour les ViewGroups personnalisés. Pour que toutes les vues personnalisées conservent leur état, vous devez remplacer onSaveInstanceState()
et onRestoreInstanceState(Parcelable state)
dans chaque classe. Vous devez également vous assurer qu'ils ont tous des identifiants uniques, qu'ils soient gonflés à partir de XML ou ajoutés par programme.
Ce que j'ai trouvé ressemblait remarquablement à la réponse de Kobor42, mais l'erreur est restée parce que j'ajoutais les vues à un ViewGroup personnalisé par programme et que je n'attribuais pas d'identifiants uniques.
Le lien partagé par mato fonctionnera, mais cela signifie qu'aucune des vues individuelles ne gère son propre état - l'état entier est enregistré dans les méthodes ViewGroup.
Le problème est que lorsque plusieurs de ces ViewGroups sont ajoutés à une mise en page, les identifiants de leurs éléments du XML ne sont plus uniques (s'ils sont définis en XML). Au moment de l'exécution, vous pouvez appeler la méthode statique View.generateViewId()
pour obtenir un identifiant unique pour une vue. Ceci n'est disponible qu'à partir de l'API 17.
Voici mon code du ViewGroup (il est abstrait et mOriginalValue est une variable de type):
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);
}
}