我正在实现我自己的自定义DialogPreference子类,它有一个用于持久化整数的SeekBar。关于需要进入onSaveInstanceState()
和onRestoreInstanceState()
的内容,我有点困惑。具体来说,您是否需要在onRestoreInstanceState()
更新用户与之交互的UI小部件(在我的情况下,是SeekBar小部件)?
我感到困惑的原因是API doc文章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小部件(如果我应该更新它...)?
答案 0 :(得分:4)
好的,经过一些实验,看起来更新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));
}