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()'也可能是相关的,以解决屏幕方向更改的问题。 –