这里的答案已经很不错了,但不一定适用于自定义ViewGroup。若要使所有自定义视图保持其状态,必须在每个类中重写onSaveInstanceState()
和onRestoreInstanceState(Parcelable state)
。您还需要确保它们都有唯一的ID,无论它们是从xml膨胀还是以编程方式添加。
我的想法非常类似于Kobor42的答案,但是错误仍然存在,因为我是通过编程将视图添加到自定义ViewGroup中的,而不是分配唯一的ID。
mato共享的链接可以使用,但是这意味着各个View都不管理自己的状态-整个状态都保存在ViewGroup方法中。
问题是,当将多个这些ViewGroup添加到布局中时,它们在xml中的元素的id不再是唯一的(如果它是在xml中定义的)。在运行时,您可以调用静态方法View.generateViewId()
以获取View的唯一ID。仅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);
}
}