Android 使用NumberPicker作为对话框首选项。为什么赢了';我的设置不能保存吗?
在这里学习android代码。我不确定我遗漏了什么,但我正在尝试创建一个自定义的Android 使用NumberPicker作为对话框首选项。为什么赢了';我的设置不能保存吗?,android,settings,sharedpreferences,numberpicker,dialog-preference,Android,Settings,Sharedpreferences,Numberpicker,Dialog Preference,在这里学习android代码。我不确定我遗漏了什么,但我正在尝试创建一个自定义的对话框preference,它使用NumberPicker让用户选择年份。我试着跟随android,但我选择的值没有保存。只要我不退出应用程序,它就会保存,但如果我退出,则在我重新启动应用程序时,它会重置为默认值。我错过了什么 设置活动代码: public class SettingsActivity extends PreferenceActivity { @Override public v
对话框preference
,它使用NumberPicker
让用户选择年份。我试着跟随android,但我选择的值没有保存。只要我不退出应用程序,它就会保存,但如果我退出,则在我重新启动应用程序时,它会重置为默认值。我错过了什么
设置活动代码:
public class SettingsActivity extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
@Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.app_preferences);
}
}
}
app_preferences.xml(设置活动的布局)
SemesterPickerPreference(DialogPreference的扩展)
公共类SemesterPickerPreference扩展了DialogPreference{
私人国际年;
私人电话窃听器;
私有int默认值;
公共符号集引用(上下文、属性集属性){
超级(上下文,attrs);
默认_值=2003;
setDialogLayoutResource(R.layout.Semmer\u picker\u对话框);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
setDialogIcon(空);
}
@凌驾
受保护的无效onDialogClosed(布尔正结果){
如果(正结果){
persistin(semPick.getValue());
}
}
@凌驾
SetInitialValue上受保护的void(布尔restorePersistedValue,对象defaultValue){
if(restorePersistedValue){
//恢复现有状态
年份=this.getPersistedInt(默认值);
}否则{
//从XML属性设置默认状态
年份=(整数)默认值;
持续(年);
}
}
@凌驾
受保护对象onGetDefaultValue(类型Darray a,整数索引){
返回一个.getInteger(索引,默认值);
}
@凌驾
受保护的视图onCreateDialogView(){
int max=2038;
int min=2001;
充气机=
(LayoutFlater)getContext().getSystemService(Context.LAYOUT\u充气机\u服务);
视图=充气机。充气(R.layout.Semmer\u picker\u对话框,空);
semPick=(NumberPicker)view.findviewbyd(R.id.semerm\u picker);
//初始化状态
semPick.setMaxValue(最大值);
semPick.setMinValue(最小值);
setValue(this.getPersistedInt(默认值));
semPick.setWrapSelectorWheel(假);
返回视图;
}
//此代码复制自android的设置指南。
私有静态类SavedState扩展了BaseSavedState{
//保存设置值的成员
//更改此数据类型以匹配您的首选项保存的类型
int值;
公共存储状态(可包裹超级状态){
超级(超级国家);
}
公共存储状态(地块源){
超级(来源);
//获取当前首选项的值
value=source.readInt();//将其更改为读取适当的数据类型
}
@凌驾
公共无效写入包裹(包裹目的地,内部标志){
超级可写包裹(目的地、旗帜);
//写入首选项的值
dest.writeInt(值);//将其更改为写入适当的数据类型
}
//使用此类实例的标准创建者对象
公共静态最终包裹。创建者=
新建Parcelable.Creator(){
public SavedState createFromParcel(中的地块){
返回新的SavedState(in);
}
public SavedState[]新数组(整数大小){
返回新的SavedState[大小];
}
};
}
@凌驾
受保护的地块onSaveInstanceState(){
最终可包裹超级状态=super.onSaveInstanceState();
//检查此首选项是否持续(持续保存)
if(isPersistent()){
//无需保存实例状态,因为它是持久的,请使用超类状态
回归超级国家;
}
//创建自定义BaseSavedState的实例
最终SavedState myState=新SavedState(超级状态);
//使用保存当前设置值的类成员设置状态值
myState.value=年;
返回我的国家;
}
@凌驾
RestoreInstanceState上的受保护无效(可包裹状态){
//检查是否将状态保存在onSaveInstanceState中
if(state==null | |!state.getClass().equals(SavedState.class)){
//没有保存状态,所以调用超类
super.onRestoreInstanceState(状态);
返回;
}
//将状态强制转换为自定义BaseSavedState并传递给超类
SavedState myState=(SavedState)状态;
super.onRestoreInstanceState(myState.getSuperState());
//设置此首选项的小部件以反映恢复的状态
semPick.setValue(myState.value);
}
}
学期选择器dialog.xml(我的学期/年度选择器的布局)
首选项XML中缺少XML属性。这就是告诉首选项是否实际将其值存储到共享首选项的原因。调用
persistin()
显然是不够的。我也遇到了类似的问题。我从@scott尝试了这个android:persistent=“true”
解决方案,但没有成功。我做了一些挖掘,在EditTextPreference
类中找到了一个解决方案
package android.preference;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.EditText;
/**
* A {@link Preference} that allows for string
* input.
* <p>
* It is a subclass of {@link DialogPreference} and shows the {@link EditText}
* in a dialog. This {@link EditText} can be modified either programmatically
* via {@link #getEditText()}, or through XML by setting any EditText
* attributes on the EditTextPreference.
* <p>
* This preference will store a string into the SharedPreferences.
* <p>
* See {@link android.R.styleable#EditText EditText Attributes}.
*/
public class EditTextPreference extends DialogPreference {
/**
* The edit text shown in the dialog.
*/
private EditText mEditText;
private String mText;
public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mEditText = new EditText(context, attrs);
// Give it an ID so it can be saved/restored
mEditText.setId(com.android.internal.R.id.edit);
/*
* The preference framework and view framework both have an 'enabled'
* attribute. Most likely, the 'enabled' specified in this XML is for
* the preference framework, but it was also given to the view framework.
* We reset the enabled state.
*/
mEditText.setEnabled(true);
}
public EditTextPreference(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
}
public EditTextPreference(Context context) {
this(context, null);
}
/**
* Saves the text to the {@link SharedPreferences}.
*
* @param text The text to save
*/
public void setText(String text) {
final boolean wasBlocking = shouldDisableDependents();
mText = text;
persistString(text);
final boolean isBlocking = shouldDisableDependents();
if (isBlocking != wasBlocking) {
notifyDependencyChange(isBlocking);
}
}
/**
* Gets the text from the {@link SharedPreferences}.
*
* @return The current preference value.
*/
public String getText() {
return mText;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
EditText editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
}
/**
* Adds the EditText widget of this preference to the dialog's view.
*
* @param dialogView The dialog view.
*/
protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
ViewGroup container = (ViewGroup) dialogView
.findViewById(com.android.internal.R.id.edittext_container);
if (container != null) {
container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
String value = mEditText.getText().toString();
if (callChangeListener(value)) {
setText(value);
}
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setText(restoreValue ? getPersistedString(mText) : (String) defaultValue);
}
@Override
public boolean shouldDisableDependents() {
return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
}
/**
* Returns the {@link EditText} widget that will be shown in the dialog.
*
* @return The {@link EditText} widget that will be shown in the dialog.
*/
public EditText getEditText() {
return mEditText;
}
/** @hide */
@Override
protected boolean needInputMethod() {
// We want the input method to show, if possible, when dialog is displayed
return true;
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.text = getText();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setText(myState.text);
}
private static class SavedState extends BaseSavedState {
String text;
public SavedState(Parcel source) {
super(source);
text = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(text);
}
public SavedState(Parcelable superState) {
super(superState);
}
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];
}
};
}
}
package.preference;
导入android.content.Context;
导入android.content.SharedReferences;
导入android.content.res.TypedArray;
导入android.os.packet;
导入android.os.Parcelable;
导入android.text.TextUtils;
导入android.util.AttributeSet;
导入android.view.view;
导入android.view.ViewGroup;
导入android.view.ViewParent;
导入android.widget.EditText;
/**
*允许使用字符串的{@link Preference}
public class SemesterPickerPreference extends DialogPreference {
private int year;
private NumberPicker semPick;
private int DEFAULT_VALUE;
public SemesterPickerPreference(Context context, AttributeSet attrs) {
super(context, attrs);
DEFAULT_VALUE = 2003;
setDialogLayoutResource(R.layout.semester_picker_dialog);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
setDialogIcon(null);
}
@Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
persistInt(semPick.getValue());
}
}
@Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
if (restorePersistedValue) {
// Restore existing state
year = this.getPersistedInt(DEFAULT_VALUE);
} else {
// Set default state from the XML attribute
year = (Integer) defaultValue;
persistInt(year);
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getInteger(index, DEFAULT_VALUE);
}
@Override
protected View onCreateDialogView() {
int max = 2038;
int min = 2001;
LayoutInflater inflater =
(LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.semester_picker_dialog, null);
semPick = (NumberPicker) view.findViewById(R.id.semester_picker);
// Initialize state
semPick.setMaxValue(max);
semPick.setMinValue(min);
semPick.setValue(this.getPersistedInt(DEFAULT_VALUE));
semPick.setWrapSelectorWheel(false);
return view;
}
// This code copied from android's settings guide.
private static class SavedState extends BaseSavedState {
// Member that holds the setting's value
// Change this data type to match the type saved by your Preference
int value;
public SavedState(Parcelable superState) {
super(superState);
}
public SavedState(Parcel source) {
super(source);
// Get the current preference's value
value = source.readInt(); // Change this to read the appropriate data type
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
// Write the preference's value
dest.writeInt(value); // Change this to write the appropriate data type
}
// 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];
}
};
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
// Check whether this Preference is persistent (continually saved)
if (isPersistent()) {
// No need to save instance state since it's persistent, use superclass state
return superState;
}
// Create instance of custom BaseSavedState
final SavedState myState = new SavedState(superState);
// Set the state's value with the class member that holds current setting value
myState.value = year;
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
// Check whether we saved the state in onSaveInstanceState
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save the state, so call superclass
super.onRestoreInstanceState(state);
return;
}
// Cast state to custom BaseSavedState and pass to superclass
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
// Set this Preference's widget to reflect the restored state
semPick.setValue(myState.value);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="horizontal"
android:gravity="center_horizontal" >
<NumberPicker
android:id="@+id/semester_picker"
android:layout_centerInParent="true"
android:layout_width="100dip"
android:layout_height="match_parent" />
</LinearLayout>
package android.preference;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.EditText;
/**
* A {@link Preference} that allows for string
* input.
* <p>
* It is a subclass of {@link DialogPreference} and shows the {@link EditText}
* in a dialog. This {@link EditText} can be modified either programmatically
* via {@link #getEditText()}, or through XML by setting any EditText
* attributes on the EditTextPreference.
* <p>
* This preference will store a string into the SharedPreferences.
* <p>
* See {@link android.R.styleable#EditText EditText Attributes}.
*/
public class EditTextPreference extends DialogPreference {
/**
* The edit text shown in the dialog.
*/
private EditText mEditText;
private String mText;
public EditTextPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mEditText = new EditText(context, attrs);
// Give it an ID so it can be saved/restored
mEditText.setId(com.android.internal.R.id.edit);
/*
* The preference framework and view framework both have an 'enabled'
* attribute. Most likely, the 'enabled' specified in this XML is for
* the preference framework, but it was also given to the view framework.
* We reset the enabled state.
*/
mEditText.setEnabled(true);
}
public EditTextPreference(Context context, AttributeSet attrs) {
this(context, attrs, com.android.internal.R.attr.editTextPreferenceStyle);
}
public EditTextPreference(Context context) {
this(context, null);
}
/**
* Saves the text to the {@link SharedPreferences}.
*
* @param text The text to save
*/
public void setText(String text) {
final boolean wasBlocking = shouldDisableDependents();
mText = text;
persistString(text);
final boolean isBlocking = shouldDisableDependents();
if (isBlocking != wasBlocking) {
notifyDependencyChange(isBlocking);
}
}
/**
* Gets the text from the {@link SharedPreferences}.
*
* @return The current preference value.
*/
public String getText() {
return mText;
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
EditText editText = mEditText;
editText.setText(getText());
ViewParent oldParent = editText.getParent();
if (oldParent != view) {
if (oldParent != null) {
((ViewGroup) oldParent).removeView(editText);
}
onAddEditTextToDialogView(view, editText);
}
}
/**
* Adds the EditText widget of this preference to the dialog's view.
*
* @param dialogView The dialog view.
*/
protected void onAddEditTextToDialogView(View dialogView, EditText editText) {
ViewGroup container = (ViewGroup) dialogView
.findViewById(com.android.internal.R.id.edittext_container);
if (container != null) {
container.addView(editText, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
}
}
@Override
protected void onDialogClosed(boolean positiveResult) {
super.onDialogClosed(positiveResult);
if (positiveResult) {
String value = mEditText.getText().toString();
if (callChangeListener(value)) {
setText(value);
}
}
}
@Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
@Override
protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
setText(restoreValue ? getPersistedString(mText) : (String) defaultValue);
}
@Override
public boolean shouldDisableDependents() {
return TextUtils.isEmpty(mText) || super.shouldDisableDependents();
}
/**
* Returns the {@link EditText} widget that will be shown in the dialog.
*
* @return The {@link EditText} widget that will be shown in the dialog.
*/
public EditText getEditText() {
return mEditText;
}
/** @hide */
@Override
protected boolean needInputMethod() {
// We want the input method to show, if possible, when dialog is displayed
return true;
}
@Override
protected Parcelable onSaveInstanceState() {
final Parcelable superState = super.onSaveInstanceState();
if (isPersistent()) {
// No need to save instance state since it's persistent
return superState;
}
final SavedState myState = new SavedState(superState);
myState.text = getText();
return myState;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (state == null || !state.getClass().equals(SavedState.class)) {
// Didn't save state for us in onSaveInstanceState
super.onRestoreInstanceState(state);
return;
}
SavedState myState = (SavedState) state;
super.onRestoreInstanceState(myState.getSuperState());
setText(myState.text);
}
private static class SavedState extends BaseSavedState {
String text;
public SavedState(Parcel source) {
super(source);
text = source.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(text);
}
public SavedState(Parcelable superState) {
super(superState);
}
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];
}
};
}
}