0

我用android's brief guide和一些谷歌搜索寫了我自己的數字選擇偏好。我的問題是關於onSaveInstanceState()方法。在谷歌的教程中,建議我們使用方法isPersistent()來確定首選項是否持久,如果是,則返回超類型。我沒有那樣做,因爲在這種情況下,如果我將數字選擇器刷到一個新數字,然後旋轉屏幕,旋轉後的版本將返回到持久值。如果我刪除這種情況,那麼一切都很好。但是,檢查其他首選項的源代碼,如edittextpreference,這種情況下存在,即使我將該值更改爲未保存的狀態,然後旋轉屏幕,狀態也會保存。有人可以解釋嗎? 這裏是我的代碼:自定義偏好isPersistent()

public class NumberPreference extends DialogPreference { 
    private final static int DEFAULT_VALUE=R.integer.timer_def; 
    private final static int DEFAULT_MIN_VALUE=R.integer.timer_min_def; 
    private final static int DEFAULT_MAX_VALUE=R.integer.timer_max_def; 
    private final int min; 
    private final int max; 
    private final String time; 

    private int timer; 
    private NumberPicker numberPicker; 


    public NumberPreference(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     setDialogLayoutResource(R.layout.number_preference); 
     setNegativeButtonText("Cancel"); 
     setPositiveButtonText("OK"); 
     TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.number_preference, 0, 0); 
     try{ 
      min=a.getInteger(R.styleable.number_preference_min, DEFAULT_MIN_VALUE); 
      max=a.getInteger(R.styleable.number_preference_max, DEFAULT_MAX_VALUE); 
      time=a.getString(R.styleable.number_preference_time); 
     }finally{ 
      a.recycle(); 
     } 
     setDialogIcon(null); 
    } 

    public void setSummary() { 
     super.setSummary("Every "+getTimer()+' '+time); 
    } 

    @Override 
    protected View onCreateView(ViewGroup parent) { 
     setSummary(); 
     return super.onCreateView(parent); 
    } 

    @Override 
    protected void onDialogClosed(boolean positiveResult) { 
     if (positiveResult) { 
      int number = numberPicker.getValue(); 
      if (callChangeListener(number)){ 
       timer=number; 
       persistInt(timer); 
       setSummary(); 
      } 
     } 
    } 

    @Override 
    protected Object onGetDefaultValue(TypedArray a, int index) { 
     return a.getInt(index,DEFAULT_VALUE); 
    } 

    @Override 
    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) { 
     if (restorePersistedValue) { 
      timer = getPersistedInt(DEFAULT_VALUE); 
     } 
     else{ 
      timer =(Integer) defaultValue; 
      persistInt(timer); 
     } 
    } 

    @Override 
    protected void onBindDialogView(View view) { 
     super.onBindDialogView(view); 
     numberPicker=(NumberPicker) view.findViewById(R.id.numpref_picker); 
     numberPicker.setMinValue(min); 
     numberPicker.setMaxValue(max); 
     numberPicker.setValue(timer); 

    } 

    public int getTimer() { 
     return getPersistedInt(DEFAULT_VALUE); 
    } 

    @Override 
    protected Parcelable onSaveInstanceState() { 
     final Parcelable superState = super.onSaveInstanceState(); 
     if (isPersistent()) { 
      return superState; 
     } 
     final SavedState myState=new SavedState(superState); 
     if (numberPicker!= null) myState.value=numberPicker.getValue(); 
     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()); 
     if (numberPicker!=null)numberPicker.setValue(myState.value); 
    } 

    private static class SavedState extends BaseSavedState { 
     // field that holds the setting's value 
     int value; 

     public SavedState(Parcelable superState) { 
      super(superState); 
     } 

     public SavedState(Parcel source) { 
      super(source); 
      // Get the current preference's value 
      value = source.readInt(); 
     } 

     @Override 
     public void writeToParcel(Parcel dest, int flags) { 
      super.writeToParcel(dest, flags); 
      // Write the preference's value 
      dest.writeInt(value); 
     } 

     // Standard creator object using an instance of this class 
     public static final Parcelable.Creator<SavedState> CREATOR = 
       new Parcelable.Creator<SavedState>() { 

        public SavedState createFromParcel(Parcel in) { 
         return new SavedState(in); 
        } 

        public SavedState[] newArray(int size) { 
         return new SavedState[size]; 
        } 
       }; 
    } 

} 

謝謝:)

回答

0

,而不必測試了它,會假設你可能需要更改

private final String time; 

private String time; 

,並通過String.valueOf(time)作爲.setSummary()方法的一個參數。當然,.onCreateView()中的發生將需要傳遞從首選項中讀取的值 - 或者如果沒有返回任何內容,則返回默認值作爲回退。儘量做得更簡單,而不是更復雜。

+0

嘿syslogic,謝謝你的答案。也許我沒有很好地解釋這個問題。字符串時間只是摘要中的一個變量,這不是我關心的問題。問題是,如果我有這種情況,我點擊打開數字選擇器,然後滑動到另一個數字比持久的數字,最後旋轉屏幕我得到的是數字選擇器回到持久值。如果我刪除了該條件,那麼旋轉的數字選擇器將指向我在旋轉之前交換的值 – michaelg9

+0

@ michaelg9希望您能夠在G +上繼續進行討論的同時工作...但setSummary()方法應該仍然是隻有一件事必須手工處理(因爲它是普通的,沒有指定顯示偏好的值 - 即使經常被濫用)。 –

+0

@ michaelg9'onConfigurationChanged()'也可能是相關的,以解決屏幕方向更改的問題。 –