簡體   English   中英

如何為DialogPreference子類正確實現onRestoreInstanceState()?

[英]How to properly implement onRestoreInstanceState() for a DialogPreference subclass?

我正在實現自己的自定義DialogPreference子類,該子類具有用於保留整數的SeekBar。 我對onSaveInstanceState()onRestoreInstanceState()需要輸入的內容有些困惑。 具體來說,您是否需要在onRestoreInstanceState()更新與用戶交互的UI小部件(在我的情況下為SeekBar小部件onRestoreInstanceState()

我感到困惑的原因是, 這里的API文檔文章告訴您這樣做:

@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 Preference類( EditTextPreferenceListPreference )的源代碼后,不會在onRestoreInstanceState()更新UI小部件。 僅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是否是持久性的,因為如果保存了mValuemMaxValue屬性,則不會保存它。 我還直接在最后調用了super.onRestoreInstanceState() ,因為我發現它在更早調用時永遠無法工作。

到目前為止,這些只是我的發現。 我不確定正確的方法是什么,但是上面的方法似乎可行。

更新:@whatyouhide想知道setValuesetMaxValue方法在我的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));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM