我正在实现我自己的自定义 DialogPreference 子类,它有一个用于保留整数的 SeekBar。我对需要进入 onSaveInstanceState()
和 onRestoreInstanceState()
的内容感到有点困惑。具体来说,您是否需要在 onRestoreInstanceState()
中更新与用户交互的 UI 小部件(在我的例子中是 SeekBar 小部件)?
我感到困惑的原因是 API 文档文章 here告诉你这样做:
@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)的源代码,UI 小部件未在 onRestoreInstanceState()
中更新。只有 Preference 的基础值是(在上面的示例中,这将是 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!
}
那么,共识是什么?我应该在哪里更新 UI 小部件(如果我应该更新它...)?
最佳答案
好吧,经过一些实验,似乎更新 onRestoreInstanceState()
中的 UI 小部件不是正确的方法,因为它似乎总是 null
观点。我不知道他们为什么建议这样做。如果子类化 Preference,也许你必须这样做,但是在子类化 DialogPreference 时要遵循不同的规则......?这至少可以解释为什么 ListPreference 和 EditTextPreference 不这样做,因为它们是 DialogPreference 的子类。
事实上,根据我的发现,UI 小部件根本不需要更新!它应该有自己的保存/恢复方法来为您处理其状态管理。例如,这是我使用 SeekBar 小部件制作的 DialogPreference 子类的摘录:
@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 想知道我的 DialogPreference 子类中的 setValue
和 setMaxValue
方法是什么样子的。他们在这里:
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));
}
关于android - 如何为 DialogPreference 子类正确实现 onRestoreInstanceState()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14181831/