Android CheckBoxPreference是否不保留选中的值?

Android CheckBoxPreference是否不保留选中的值?,android,Android,我有这个偏好 <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > <CheckBoxPreference android:defaultValue="true" android:key="sound" android:summary="Sound ON/OFF

我有这个偏好

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >

<CheckBoxPreference
    android:defaultValue="true"
    android:key="sound"
    android:summary="Sound ON/OFF"
    android:title="Sound" >
</CheckBoxPreference>

<PreferenceScreen
    android:key="videos"
    android:persistent="false"
    android:summary="Click to select videos"
    android:title="Videos" >
    <CheckBoxPreference
        android:defaultValue="true"
        android:icon="@drawable/ic_launcher_crimson"
        android:key="crimson"
        android:title="Cimson Cartoon" />
    <CheckBoxPreference
        android:defaultValue="false"
        android:icon="@drawable/ic_launcher_darkgreen"
        android:key="darkgreen"
        android:title="Dark Green Cartoon" />
    <CheckBoxPreference
        android:defaultValue="false"
        android:icon="@drawable/ic_launcher_openfieldrifle"
        android:key="openfieldrifle"
        android:title="Open Field with Bullet Bill, Assault Rifle" />
    <CheckBoxPreference
        android:defaultValue="false"
        android:icon="@drawable/ic_launcher_openfieldshotgun"
        android:key="openfiledshotgun"
        android:title="Open Field Cartoon Shotgun" />
    <CheckBoxPreference
        android:defaultValue="false"
        android:icon="@drawable/ic_launcher_submachine"
        android:key="submachine"
        android:title="Submachine Dark Mist" />
    <CheckBoxPreference
        android:defaultValue="false"
        android:icon="@drawable/ic_launcher_violet"
        android:key="violet"
        android:title="Violet Cartoon" />
</PreferenceScreen>

</PreferenceScreen>
例如:

但这是我的日志显示的


我发现您的代码有两个问题。一个是,您只在
crimsonPreference
上调用
setonpreferencechangelister
。您需要对所有
首选项
对象执行此操作。第二个问题是,您无法调用从侦听器获取
首选项的值,因为该值尚未更新,根据文档:

设置当用户更改此首选项时(但在内部状态更新之前)要调用的回调


我发现你的代码有两个问题。一个是,您只在
crimsonPreference
上调用
setonpreferencechangelister
。您需要对所有
首选项
对象执行此操作。第二个问题是,您无法调用从侦听器获取
首选项的值,因为该值尚未更新,根据文档:

设置当用户更改此首选项时(但在内部状态更新之前)要调用的回调


您的问题来自以下方面:

getPreferenceManager().setSharedPreferencesName("prefs");
    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
如果你移除它,它应该可以工作。如果要保留该行,则应尝试替换该行:

getPreferenceManager().setSharedPreferencesName("prefs");
    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
通过这个:

SharedPreferences sharedPref = getSharedPreferences("prefs", MODE_PRIVATE);

我希望它能帮助您。

您的问题来自以下方面:

getPreferenceManager().setSharedPreferencesName("prefs");
    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
如果你移除它,它应该可以工作。如果要保留该行,则应尝试替换该行:

getPreferenceManager().setSharedPreferencesName("prefs");
    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
通过这个:

SharedPreferences sharedPref = getSharedPreferences("prefs", MODE_PRIVATE);

我希望它能帮助您。

当您从
SharedReferences
读取首选项值时,您正在读取以前设置的值(即,在选中或取消选中
复选框首选项之前)

也就是说,在您的侦听器中,您必须确保反转未选中的首选项的值(因为这就是将要发生的事情)

因此,
onPreferenceChange()
应该如下所示:

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {

    if ((Boolean)newValue) {
        // Just fall through and enable the option
        return true;
    }

    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
    crimson = sharedPref.getBoolean("crimson", true) // default return value should be true for this
            && !preference.equals(crimsonpreference);
    darkgreen = sharedPref.getBoolean("darkgreen", false)
            && !preference.equals(darkgreenpreference);
    openfieldrifle = sharedPref.getBoolean("openfieldrifle", false)
            && !preference.equals(openfieldriflepreference);
    openfiledshotgun = sharedPref.getBoolean("openfiledshotgun", false)
            && !preference.equals(openfiledshotgunpreference);
    submachine = sharedPref.getBoolean("submachine", false)
            && !preference.equals(submachinepreference);
    violet = sharedPref.getBoolean("violet", false)
            && !preference.equals(violetpreference);

    if (darkgreen || openfieldrifle || openfiledshotgun || submachine || violet) {
        return true;
    }
    // If now create a message to the user
    else {
        Toast.makeText(MyPreferencesActivity.this,
                "Please select at least one video ", Toast.LENGTH_SHORT)
                .show();
        return false;
    }
}

希望这有帮助。

当您从
SharedReferences
读取首选项值时,您正在读取以前设置的值(即,在选中或取消选中
复选框首选项之前)

也就是说,在您的侦听器中,您必须确保反转未选中的首选项的值(因为这就是将要发生的事情)

因此,
onPreferenceChange()
应该如下所示:

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {

    if ((Boolean)newValue) {
        // Just fall through and enable the option
        return true;
    }

    SharedPreferences sharedPref = PreferenceManager
            .getDefaultSharedPreferences(MyPreferencesActivity.this);
    crimson = sharedPref.getBoolean("crimson", true) // default return value should be true for this
            && !preference.equals(crimsonpreference);
    darkgreen = sharedPref.getBoolean("darkgreen", false)
            && !preference.equals(darkgreenpreference);
    openfieldrifle = sharedPref.getBoolean("openfieldrifle", false)
            && !preference.equals(openfieldriflepreference);
    openfiledshotgun = sharedPref.getBoolean("openfiledshotgun", false)
            && !preference.equals(openfiledshotgunpreference);
    submachine = sharedPref.getBoolean("submachine", false)
            && !preference.equals(submachinepreference);
    violet = sharedPref.getBoolean("violet", false)
            && !preference.equals(violetpreference);

    if (darkgreen || openfieldrifle || openfiledshotgun || submachine || violet) {
        return true;
    }
    // If now create a message to the user
    else {
        Toast.makeText(MyPreferencesActivity.this,
                "Please select at least one video ", Toast.LENGTH_SHORT)
                .show();
        return false;
    }
}

希望这有帮助。

您有多少相同的听众?另外,将stacktrace作为文本发布,这是不可读的。@njzk2感谢njzk2,如果您仔细看,它们是不相同的。日志通常显示
crimson=true
darkgreen=false
openfieldrifle=false
openfieldshotgun=false
submachine=false
violet=false
。关键是我希望darkgreen=true实际上,您只需要一个侦听器。@Tobor谢谢Tobor,但我认为问题不在这里:-((您希望至少选中一个复选框?初始状态是什么(例如,所有复选框均未选中)在任何用户交互之前?您有多少个相同的侦听器?另外,将stacktrace作为文本发布,这是不可读的。@njzk2感谢njzk2,如果您仔细查看它们不相同的话。日志通常显示
crimson=true
darkgreen=false
openfieldrifle=false
openfieldshotgun=false
de>submachine=false
violet=false
。问题是,我希望darkgreen=true确实,您只需要一个侦听器。@Tobor谢谢Tobor,但我认为问题不在这里:-((您希望至少选中一个复选框?初始状态是什么(例如,所有复选框均未选中)在任何用户交互之前?thak you Scott,我确实在所有首选项上都设置了一个侦听器(但不想发布整个内容)。问题是,正如您从“crimson”侦听器内部看到的,darkgreen的值为FALSE,但在选中
crimson
之前,我选中了
darkgreen
复选框……因此您的声明:“设置当用户更改此首选项时调用的回调(但在内部状态更新之前)”,在这种情况下不适用:-(((thak you Scott,我确实在所有首选项上设置了一个侦听器(但不希望发布整个内容)。问题是,正如您从“crimson”中可以看到的“listener,darkgreen的值为FALSE,但在选中
crimson
之前,我选中了
darkgreen
复选框……因此您的语句:“设置当用户更改此首选项时(但在内部状态更新之前)”不适用于这种情况!:-((((删除
getPreferenceManager()。setSharedPreferencesName(“prefs”);
成功了。谢谢Addrallyn!!!!删除
getPreferenceManager()。setSharedPreferencesName(“prefs”);
成功了。谢谢Addrallyn!!!!