Xåp*_* - 8 android state android-widget android-preferences dialog-preference
我正在实现我自己的自定义DialogPreference子类,它具有用于持久化整数的SeekBar.我有点困惑什么需要进入onSaveInstanceState()和onRestoreInstanceState().具体来说,您是否需要更新用户与之交互的UI小部件(在我的情况下,是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!
}
Run Code Online (Sandbox Code Playgroud)
但是查看一些官方Android Preference类(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!
}
Run Code Online (Sandbox Code Playgroud)
那么,共识是什么?我应该更新UI小部件(如果我应该更新它...)?
Xåp*_* - 4
好吧,经过一些实验,看起来更新里面的 UI 小部件onRestoreInstanceState()并不是可行的方法,因为它似乎总是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());
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我从未在任何地方更新 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));
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2156 次 |
| 最近记录: |