Я успешно реализовал onRetainNonConfigurationInstance ()
для моей основной деятельности
, чтобы сохранить и восстановить некоторые критические компоненты при изменении ориентации экрана.
Но, похоже, мои пользовательские виды воссоздаются с нуля, когда меняется ориентация. Это имеет смысл, хотя в моем случае это неудобно, поскольку рассматриваемый пользовательский вид представляет собой график X / Y, а точки на графике сохраняются в пользовательском представлении.
Есть ли хитрый способ реализовать что-то похожее на onRetainNonConfigurationInstance ()
для настраиваемого представления, или мне нужно просто реализовать методы в настраиваемом представлении, которые позволяют мне получать и устанавливать его «состояние» ?
Вы делаете это, реализуя View#onSaveInstanceState
и View#onRestoreInstanceState
и расширяя класс View.BaseSavedState
.
public class CustomView extends View {
private int stateToSave;
...
@Override
public Parcelable onSaveInstanceState() {
//begin boilerplate code that allows parent classes to save state
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
//end
ss.stateToSave = this.stateToSave;
return ss;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
//begin boilerplate code so parent classes can restore state
if(!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState)state;
super.onRestoreInstanceState(ss.getSuperState());
//end
this.stateToSave = ss.stateToSave;
}
static class SavedState extends BaseSavedState {
int stateToSave;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
this.stateToSave = in.readInt();
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeInt(this.stateToSave);
}
//required field that makes Parcelables from a Parcel
public static final Parcelable.Creator<SavedState> CREATOR =
new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}
Работа разделена между классом View и SavedState View. Вы должны выполнять всю работу по чтению и записи в и из Parcel
в классе SavedState
. Затем ваш класс View может выполнить работу по извлечению членов состояния и выполнить работу, необходимую для возврата класса в допустимое состояние.
Примечания: View#onSavedInstanceState
и View#onRestoreInstanceState
вызываются автоматически, если View#getId
возвращает значение >= 0. Это происходит, когда вы дайте ему идентификатор в xml или вызовите setId
вручную. В противном случае вам нужно вызвать View#onSaveInstanceState
и записать Parcelable, возвращенный посылке, которую вы получаете в Activity#onSaveInstanceState
, чтобы сохранить состояние, а затем прочитать его и передать View #onRestoreInstanceState
из Activity#onRestoreInstanceState
.
Другим простым примером этого является CompoundButton