8

私は自分のカスタムDialogPreferenceサブクラスを実装しています。このサブクラスには、整数を保持するためのSeekBarがあります。私はonSaveInstanceState()onRestoreInstanceState()に入る必要があることについて少し混乱しています。具体的には、ユーザが対話するUIウィジェット(私の場合はSeekBarウィジェット)をonRestoreInstanceState()に更新する必要がありますか?私は混乱していますDialogPreferenceサブクラスに対してonRestoreInstanceState()を正しく実装する方法は?

理由は、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の優先クラス(EditTextPreferenceListPreference)のソースを見て、UIウィジェットがされ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! 
} 

、コンセンサスは何ですか? UIウィジェットを更新するはずです(もし私がUIウィジェットを更新しなければならないのなら...)?

答えて

4

いいえ、いくつかの実験の後で、onRestoreInstanceState()内のUIウィジェットを更新するように見えるのは、その時点で常にnullと思われるためです。なぜ彼らがそれを提案するのか分かりません。おそらく、Preferenceをサブクラス化する必要があるかもしれませんが、DialogPreferenceをサブクラス化する際には、異なる規則があります...?これは少なくとも、ListPreferenceとEditTextPreferenceがDialogPreferenceをサブクラス化する理由を説明します。

実際、私が見つけたことから、UIウィジェットはまったく更新する必要はありません!それはあなたのための状態管理を処理する独自の保存/復元メソッドを持っている必要があります。

@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()); 
} 

をあなたが見ることができるように、私はどこでもシークバーウィジェットを更新することはありません:たとえば、ここで私はそれにシークバーウィジェットで作られたDialogPreferenceサブクラスの抜粋です。 SeekBarは、その状態をすべて保存/復元します。

また、Androidデベロッパーのドキュメントに示唆されているものと若干の違いがあることに気づくでしょう。私は状態が保存される前にDialogPreferenceが永続的であるかどうかチェックしません。mValuemMaxValueのプロパティは保存されていないため保存されません。私はまた、最後にsuper.onRestoreInstanceState()と呼んでいます。以前に呼ばれたときにはうまくいかないことがわかったので、

これはこれまでの私の知見です。私は正しい方法が何であるか分かりませんが、私が上にしていることはうまくいくようです。

更新:@whatyouhideは、DialogPreferenceサブクラスでsetValuesetMaxValueのように見えます。ここにあります:

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)); 
} 
+0

カスタム 'DialogPreference'で定義した' setValue'と 'setMaxValue'メソッドはありますか?もしそうなら、それらのメソッドのコードを投稿できますか? – whatyouhide

+0

@whatyouhideはい。私の更新された答えを見てください。 –

+0

Mmmm、ありがとう。私の問題は、 'DialogPreference.getValue()'がダイアログ内のいくつかの 'View'sから値を取得し、' onSaveInstanceState'と 'onRestoreInstanceState'が呼び出されたときにこれらのビューが' null'ポインタであることです。 – whatyouhide

関連する問題