여기에 대한 답변은 이미 훌륭하지만 사용자 정의 ViewGroup에 반드시 작동하는 것은 아닙니다. 모든 사용자 정의보기가 자신의 상태를 유지하기 위해 얻으려면, 당신은 오버라이드 (override) 할 필요 onSaveInstanceState()
와 onRestoreInstanceState(Parcelable state)
각 클래스이다. 또한 XML에서 팽창되었거나 프로그래밍 방식으로 추가되었는지 여부에 관계없이 모두 고유 한 ID를 갖도록해야합니다.
내가 생각해 낸 것은 Kobor42의 대답과 매우 비슷하지만 프로그래밍 방식으로 사용자 정의 ViewGroup에 뷰를 추가하고 고유 ID를 할당하지 않았기 때문에 오류가 계속 발생했습니다.
mato가 공유하는 링크는 작동하지만 개별 뷰가 자신의 상태를 관리하지 않음을 의미합니다. 전체 상태는 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);
}
}