【问题标题】:Get and set preference values获取和设置首选项值
【发布时间】:2017-06-10 05:53:49
【问题描述】:

我的目标是管理我的自定义偏好。为此,我有以下代码:

MainActivity.java

public class MainActivity extends ActionBarActivity implements View.OnTouchListener, GoogleMap.OnInfoWindowClickListener, LocationListener, GoogleMap.OnMapClickListener{

             public boolean onOptionsItemSelected(MenuItem item) {
                int id = item.getItemId();

                if (id == R.id.action_settings) {
                    launchPreferences(null);
                    return true;
                }

                return super.onOptionsItemSelected(item);
            }
            public void launchPreferences(View view) {
                Intent i = new Intent(this, Preferences.class);
                startActivity(i);
            }
    }

Preferences.java

public class Preferences extends PreferenceActivity {

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

        updatePreference();


    }

settings.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="@+id/preferencias_principal" >
    <EditTextPreference
        android:key="@+id/perimer"
        android:title="Perimeter to list"
        android:summary="Maximum distance to list"
        android:defaultValue="2"/>
    <ListPreference
        android:key="@+id/leguage"
        android:title="Lenguage"
        android:summary="What language would you apply?"
        android:entries="@array/lenguage"
        android:entryValues="@array/lenguageva"
        android:defaultValue="1"/>

</PreferenceScreen>

arrays.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="lenguage">
        <item>English</item>
        <item>Basque</item>
        <item>Spanish</item>
    </string-array>
    <string-array name="lenguageva">
        <item>1</item>
        <item>2</item>
        <item>3</item>
    </string-array>

    <string-array name="number">
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
        <item>9</item>
        <item>10</item>
        <item>11</item>
        <item>12</item>
        <item>13</item>
        <item>14</item>
        <item>15</item>
    </string-array>

</resources>

我想使用以下代码获取此首选项的值:

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
Integer peri = sharedPref.getInt("@+id/perimer", 1);
Integer leng = sharedPref.getInt("@+id/leguage", 2);

但此代码返回默认值,peri=1 和 leng=2

不仅如此,有时偏好活动添加的信息会被更改/删除,或者在 ListPreference 项中不会出现默认选择的项(如图所示)。

当我使用调试器执行可见的代码here时,结果如下:

我能做什么?

谢谢!

【问题讨论】:

  • 在下面查看我的答案。希望您能理解 SharedPreferences 的正确使用。

标签: java android android-preferences


【解决方案1】:

主要问题是您用于EditTextPreferenceListPreference 的密钥@+id/perimer@+id/leguage

SharedPreferences 无法将其识别为首选项KEY。当您添加资源前缀@+id 时,它被视为int 资源id 这就是为什么它仍然可以使用以下行但会出现异常行为并给您不正确的输出。

    Integer peri = sharedPref.getInt("@+id/perimer", 1); // WRONG
    Integer leng = sharedPref.getInt("@+id/leguage", 2); // WRONG

解决方案:

1. 不要使用资源前缀@+id 优先KEY。更新您的settings.xml 如下:

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

    <EditTextPreference
        android:key="perimer"
        android:title="Perimeter to list"
        android:summary="Maximum distance to list"
        android:defaultValue="2"/>
    <ListPreference
        android:key="leguage"
        android:title="Lenguage"
        android:summary="What language would you apply?"
        android:entries="@array/lenguage"
        android:entryValues="@array/lenguageva"
        android:defaultValue="1"/>

</PreferenceScreen>

2.使用SharedPreferences.getString(KEY_NAME, DEFAULT_VALUE)获取偏好值。

    // Get current values
    String peri = mSharedPreferences.getString("perimer", "1");
    String leng = mSharedPreferences.getString("leguage", "2");

3.OnPreferenceChangeListener 添加到您的preferences 以获取更新后的values 并根据需要更新首选项summary

    // Required to get the updated value and update summary when you input distance
    mPreferencePerimer.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {
            String peri = value.toString();

            //Update premier summary
            mPreferencePerimer.setSummary(peri);

            return true;
        }
    });

    // Required to get the updated value and update summary when you change language from list
    mPreferenceLeguage.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object value) {

            String leng = value.toString();
            int lengIndex = Integer.parseInt(leng) - 1;

            // Update leguage summary
            mPreferenceLeguage.setSummary(mPreferenceLeguage.getEntries()[lengIndex]);
            return true;
        }
    });

这是完整的代码:

public class Preferences extends PreferenceActivity {

    // Preference Keys
    public static final String KEY_PREF_PERIMER = "perimer";
    public static final String KEY_PREF_LEGUAGE = "leguage";

    // Shared preference
    SharedPreferences mSharedPreferences;

    EditTextPreference mPreferencePerimer;
    ListPreference mPreferenceLeguage;

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

        // Shared preference
        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

        // Perimer
        mPreferencePerimer = (EditTextPreference) getPreferenceScreen().findPreference(KEY_PREF_PERIMER);
        // Leguage
        mPreferenceLeguage = (ListPreference) getPreferenceScreen().findPreference(KEY_PREF_LEGUAGE);

        // Get current values
        String peri = mSharedPreferences.getString(KEY_PREF_PERIMER, "1");
        String leng = mSharedPreferences.getString(KEY_PREF_LEGUAGE, "2");
        int lengIndex = Integer.parseInt(leng) - 1;

        // Set preference summary
        mPreferencePerimer.setSummary(peri);
        mPreferenceLeguage.setSummary(mPreferenceLeguage.getEntries()[lengIndex]);

        // Required to get the updated value and update summary when you input distance
        mPreferencePerimer.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object value) {
                String peri = value.toString();

                //Update premier summary
                mPreferencePerimer.setSummary(peri);

                return true;
            }
        });

        // Required to get the updated value and update summary when you change language from list
        mPreferenceLeguage.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object value) {

                String leng = value.toString();
                int lengIndex = Integer.parseInt(leng) - 1;

                // Update leguage summary
                mPreferenceLeguage.setSummary(mPreferenceLeguage.getEntries()[lengIndex]);
                return true;
            }
        });
    }
}

输出:

默认状态

改变后

希望对你有所帮助~

【讨论】:

    【解决方案2】:

    我已经做了类似的事情,我认为这应该可行。但此代码未经测试,可能会引发一些错误。

    public class Preferences extends PreferenceActivity implements android.preference.Preference.OnPreferenceChangeListener {
    private ListPreference lang_list;    
    
    @Override protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);
        SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
        // get the stored (or default) value (the index of the selected item)
        Integer leng = sharedPref.getInt("@+id/leguage", 2);
    
        // get the reference of the ListPreference defined in settings.xml
        lang_list = (ListPreference) getPreferenceManager().findPreference("@+id/leguage");
        // set the selected value
        lang_list.setValueIndex(leng);
        // add a listener to get the changes made by the user. Your Preferences class should implement the OnPreferenceChangeListener interface
        lang_list.setOnPreferenceChangeListener(this);
      }
    
      ...
    
      /// When the user selects an item from the list, this function will be fired
      public boolean onPreferenceChange(Preference preference, Object newValue) {
        String key = preference.getKey();
        // ensure that the change has been in the language list
        if (key.equals(lang_list.getKey())) {
          SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
          // set the value for the key "@+id/leguage"
          sharedPref.putInt("@+id/leguage", (int) newValue);
          // save the sharedPref object to the file system
          sharedPref.apply();
          return true;
        }
        return false;
      }

    2017/06/09 更新:您的 Preferences 类必须实现 android.preference.Preference.OnPreferenceChangeListener 接口才能使用 lang_list.setOnPreferenceChangeListener(this);

    【讨论】:

    • lang_list 是一个私有值,不是吗?另一方面,在这部分代码lang_list.setValueIndex (leng); 中,我的 lang_list 值有一个错误,因为它是 null 并且当执行lang_list.setValueIndex (leng); 时,应用程序关闭。
    • lang_list 是 private ListPreference lang_list; 类的成员。您收到 NullReference 错误,因为没有带有键 leguage 的 ListPreference,它应该是 lang_list = .....findPreference("@+id/leguage");,因为这是 settings.xml 中的 android:key
    • 使用最新的代码我可以看到 lang_list 为空,正如您在帖子中看到的那样。
    • 你到底在执行什么代码?您是否插入了初始 super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings); updatePreference(); 在我给你的代码中?我的“onCreate”函数的“...”意味着您必须将以前的代码放在那里。 null 值似乎没有加载任何首选项。
    • 与我发布的代码相同,但实现了一些无关紧要的更改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 1970-01-01
    • 2011-05-28
    • 2014-10-10
    • 2014-03-16
    相关资源
    最近更新 更多