Відповіді тут вже чудові, але вони не обов'язково працюють для користувацьких ViewGroups. Щоб отримати всі власні перегляди для збереження їх стану, ви повинні перекрити їх onSaveInstanceState()і onRestoreInstanceState(Parcelable state)в кожному класі. Вам також потрібно переконатися, що всі вони мають унікальні ідентифікатори, незалежно від того, чи вони завищені від xml чи додані програмно.
Те, що я придумав, було надзвичайно схожим на відповідь Kobor42, але помилка залишилася, оскільки я додавав перегляди до користувацького ViewGroup програмно і не призначав унікальні ідентифікатори.
Посилання, яким поділяється mato, буде працювати, але це означає, що жоден з окремих представлень не управляє власним станом - весь спосіб зберігається методами ViewGroup.
Проблема полягає в тому, що коли декілька цих ViewGroups додаються до макета, ідентифікатори їх елементів із xml вже не є унікальними (якщо їх визначено у xml). Під час виконання ви можете викликати статичний метод, View.generateViewId()щоб отримати унікальний ідентифікатор для представлення даних. Це доступно лише в API 17.
Ось мій код з ViewGroup (він абстрактний, а mOriginalValue - змінна тип):
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);
}
}