安卓SharedPreferences/PreferenceFragment无法工作

3

我最近学习了关于使用共享首选项PreferenceFragment来处理应用程序首选项的部分,在Android开发者文档中,并制作了以下简单示例:

SettingsActivity.java

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(savedInstanceState == null)
            getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit()

    }

}

SettingsFragment.java

public class SettingsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
    }

}

res/xml/settings.xml

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

    <PreferenceCategory android:title="@string/pref_general_category">    

        <EditTextPreference
            android:key="@id/pref_key_apiBaseUri"
            android:title="@string/pref_apiBaseUri_title"
            android:defaultValue="@string/pref_apiBaseUri_default"
            android:persistent="true"
            android:inputType="text"
            android:singleLine="true" />

    </PreferenceCategory>

</PreferenceScreen>

其他事项:

id        pref_key_apiBaseUri
string    pref_apiBaseUri_title       "Api Base Uri"
string    pref_api_baseUri_default    "http://acme.com/api/

问题

看起来很简单,是吧?我启动了应用程序,进入了首选项菜单/活动,首选项片段被填充,然后我点击了“Api Base Uri”。一个EditText对话框弹了出来,我将“http://acme.com/api”改为“http://acme.com/api2”,然后按下了确定。现在,据我所理解的文档,首选项应该自动保存到共享首选项中。当我重新打开EditText对话框时,我发现我的更改已经保存。

但是...当我关闭活动(或应用程序)并返回设置时,默认值又回来了,没有进行任何更改!我该怎么做才能永久保存我的设置?

1个回答

4
在您的settings.xml文件中,您有以下内容:
<EditTextPreference
    android:key="@id/pref_key_apiBaseUri"
    android:title="@string/pref_apiBaseUri_title"
    android:defaultValue="@string/pref_apiBaseUri_default"
    android:persistent="true"
    android:inputType="text"
    android:singleLine="true" />

根据android:key的文档,您必须为键指定一个字符串:

对于持久化数据值的首选项,此属性是必需的。它指定了系统在将此设置的值保存在SharedPreferences中时使用的唯一键(字符串)。

看起来您的pref_key_apiBaseUri是一个空字符串。请将其更改为有效的字符串并移到strings.xml文件中:

<string name="pref_key_apiBaseUri">KEY</string>

接着按如下方式使用:

<EditTextPreference
    android:key="@string/pref_key_apiBaseUri"
    ...

或者保持原样,在id标签前加上+,这将创建一个id,然后将其用作键:

<EditTextPreference
    android:key="@+id/pref_key_apiBaseUri"
    ...

我已经在/res/values/ids.xml中定义了我的id,如下所示:<item type="id" name="pref_key_apiBaseUri" />。这不应该有效吗? - Acrotygma
我知道了。我不确定为什么它不起作用。我可以看到文档中只使用字符串而不是 ID 引用,你的问题似乎出现在 android:key 元素中,如上所述... - Melquiades
哦,你说得对。引用的id似乎不起作用,尽管很有趣,因为设置键应该是唯一的,因此也是一个id。使用字符串解决了我的问题,谢谢。 - Acrotygma
非常感谢。我花了很多时间来研究这个问题,但是......我忘记了一些偏好设置的关键。不会再忘记了 :) - dustinrwh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接