Как правильно реализовать onRestoreInstanceState() для подкласса DialogPreference?
Я реализую свой собственный подкласс DialogPreference, в котором SeekBar используется для сохранения целого числа. Я немного запутался в том, что нужно onSaveInstanceState()
а также onRestoreInstanceState()
, В частности, нужно ли обновить виджет пользовательского интерфейса, с которым взаимодействует пользователь (в моем случае, виджет SeekBar) в onRestoreInstanceState()
?
Причина, по которой я запутался, заключается в том, что в статье, посвященной API doc, вам сказано сделать это:
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = mNewValue; //<------------ saves mNewValue
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
mNumberPicker.setValue(myState.value); //<------------ updates the UI widget, not mNewValue!
}
Но если посмотреть на источник некоторых официальных классов настроек Android ( EditTextPreference и ListPreference), виджет пользовательского интерфейса не обновляется в onRestoreInstanceState()
, Только базовое значение предпочтения (в приведенном выше примере это было бы mNewValue
).
Вот соответствующий источник для EditTextPreference:
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
return superState;
}
final SavedState myState = new SavedState(superState);
myState.value = getValue(); //<---- saves mValue
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setValue(myState.value); //<---- updates mValue, NOT the UI widget!
}
Итак, каков консенсус? Где я должен обновить виджет пользовательского интерфейса (если я вообще должен его обновлять...)?
1 ответ
Хорошо, после некоторых экспериментов, это похоже на обновление виджета интерфейса пользователя внутри onRestoreInstanceState()
это не путь, потому что это всегда кажется null
в таком случае. Я не знаю, почему они предлагают это. Возможно, вам придется сделать это, если вы создадите подклассификацию Preference, но существуют другие правила, которым нужно следовать при создании подкласса DialogPreference...? Это, по крайней мере, объясняет, почему ListPreference и EditTextPreference этого не делают, потому что они являются подклассом DialogPreference.
Фактически, из того, что я нашел, виджет пользовательского интерфейса вообще не нуждается в обновлении! Он должен иметь свои собственные методы сохранения / восстановления, которые управляют его управлением состоянием для вас. Например, вот выдержка из подкласса DialogPreference, который я сделал с виджетом SeekBar:
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
final SavedState myState = new SavedState(superState);
myState.maxValue = getMaxValue(); //<---- saves mMaxValue
myState.value = getValue(); //<---- saves mValue
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class))
{
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
setMaxValue(myState.maxValue); //<---- updates mMaxValue
setValue(myState.value); //<---- updates mValue
super.onRestoreInstanceState(myState.getSuperState());
}
Как видите, я никогда нигде не обновляю виджет SeekBar. SeekBar самостоятельно сохранит / восстановит свое состояние!
Вы также заметите, что есть некоторые небольшие отклонения от того, что предлагается в документации для разработчиков Android. Я не проверяю, является ли DialogPreference постоянным перед сохранением состояния, потому что тогда mValue
а также mMaxValue
свойства не будут сохранены, если это так. Я тоже звоню super.onRestoreInstanceState()
прямо в конце, как я обнаружил, что он никогда не работает, когда он вызывается раньше.
Это только мои выводы. Я не уверен, что правильный путь, но то, что я имею выше, кажется, работает.
ОБНОВЛЕНИЕ: @whatyouhide хочет знать, что setValue
а также setMaxValue
методы выглядят как в моем подклассе DialogPreference. Вот они:
public void setValue(int value)
{
value = Math.max(Math.min(value, mMaxValue), mMinValue);
if (value != mValue)
{
mValue = value;
persistInt(value);
notifyChanged();
}
}
public void setMaxValue(int maxValue)
{
mMaxValue = maxValue;
setValue(Math.min(mValue, mMaxValue));
}