赞
踩
Context.getSharedPreferences(String name, int mode)
由于Activity中已经存在Context的实例,所以在Activity中可以直接通过getSharedPreferences(String, int)获取SharedPreferences的实例
参数说明
name:SharedPreferences存储的文件名,如果name不存在,则会在Editor.commit()后创建
mode:创建模式,值为0或者其他的值,我们一般填0应用内访问就可以了,详情查看
PreferenceManager.getDefaultSharedPreferences(Context context)
我这里用的是android.support.v7.preference库,使用的时候需要在App gradle中配置dependencies
如下图所示
代码如下
implementation 'com.android.support:preference-v7:28.0.0'
SharedPreferences.edit(),获取SharedPreferences.Editor的实例
字符串赋值:putString(String key, String value)
clear()
提交有一下两种方式,修改数据完成后需要执行提交的方法才会完成修改
(1)、apply()
(2)、commit()
SharedPreferences.Editor更多的使用方法参考链接
查看数据是基于SharedPreferences的实例进行操作
如:getString(String key, String defValue)
更多查看方式链接
这里用到的key字符串与及其它字符串默认值建议使用引用静态资源的方式赋值,详情参考链接
注意,在使用静态资源赋值到key时,需要设置translatable属性为false,防止国际化等其它原因导致key值被转换,设置如下所示:
<string name="pref_size_key" translatable="false">size</string>
布尔类型的默认值建议也是用资源引用的方式赋值,详情参考链接
在需要监听的类里面实现SharedPreferences.OnSharedPreferenceChangeListener接口
比如在Activity中实现接口SharedPreferences.OnSharedPreferenceChangeListener,实现接口的方法onSharedPreferenceChanged
比如下面的实现代码:
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- if (key.equals(“signature”)) {
- Log.i(TAG, “Preference value was updated to: “ + sharedPreferences.getString(key, ""));
- }
- }
通过SharedPreferences的registerOnSharedPreferenceChangeListener方法注册一个监听器
- @Override
- public void onResume() {
- super.onResume();
- getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
- }
如果注册了监听,则需要在退出的时候取消注册监听:
- @Override
- public void onPause() {
- super.onPause();
- getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
- }
需要注意的是,我前面注册的是默认的SharedPreferences,所以取消注册的时候我也是先获取的默认的SharedPreferences。
其实还有对应的activity的实现,但是谷歌官方推荐使用Fragment,使用更灵活。
在fragment中继承PreferenceFragmentCompat,实现方法onCreatePreferences,从xml资源文件中添加preferences:
- @Override
- public void onCreatePreferences(Bundle bundle, String s) {
- addPreferencesFromResource(R.xml.pref_visualizer);
- }
pref_visualizer资源文件如下
- <?xml version="1.0" encoding="utf-8"?>
- <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
- <CheckBoxPreference
- android:defaultValue="@bool/pref_show_bass_default"
- android:key="@string/pref_show_bass_key"
- android:summaryOff="@string/hidden"
- android:summaryOn="@string/show"
- android:title="@string/show_base_label" />
- <CheckBoxPreference
- android:defaultValue="@bool/pref_show_mid_default"
- android:key="@string/pref_show_mid_key"
- android:summaryOff="@string/hidden"
- android:summaryOn="@string/show"
- android:title="@string/show_mid_label" />
- <CheckBoxPreference
- android:defaultValue="@bool/pref_show_treble_default"
- android:key="@string/pref_show_treble_key"
- android:summaryOff="@string/hidden"
- android:summaryOn="@string/show"
- android:title="@string/show_treble_label" />
- <EditTextPreference
- android:defaultValue="@string/pref_size_default"
- android:key="@string/pref_size_key"
- android:title="@string/setting_size_label"/>
- <ListPreference
- android:defaultValue="@string/pref_color_red_value"
- android:entries="@array/pref_color_option_labels"
- android:entryValues="@array/pref_color_option_values"
- android:key="@string/pref_color_key"
- android:title="@string/selector_color" />
- </PreferenceScreen>

这里的EditTextPreference和ListPreference默认没有描述值,需要在代码中添加描述
- @Override
- public void onCreatePreferences(Bundle bundle, String s) {
- addPreferencesFromResource(R.xml.pref_visualizer);
- PreferenceScreen preferenceScreen = getPreferenceScreen();
- SharedPreferences sharedPreferences = preferenceScreen.getSharedPreferences();
- int count = preferenceScreen.getPreferenceCount();
- for (int i = 0; i < count; i++) {
- Preference preference = preferenceScreen.getPreference(i);
- if (!(preference instanceof CheckBoxPreference)) {
- String value = sharedPreferences.getString(preference.getKey(), getString(R.string.pref_color_red_value));
- setupPreferenceSummary(preference, value);
- }
- }
- Preference preference = findPreference(getString(R.string.pref_size_key));
- preference.setOnPreferenceChangeListener(this);
- }
-
- private void setupPreferenceSummary(Preference preference, String s) {
- if (preference instanceof ListPreference) {
- ListPreference listPreference = (ListPreference) preference;
- int position = listPreference.findIndexOfValue(s);
- if (position >= 0) {
- listPreference.setSummary(listPreference.getEntries()[position]);
- }
- } else if (preference instanceof EditTextPreference) {
- EditTextPreference editTextPreference = (EditTextPreference) preference;
- editTextPreference.setSummary(s);
- }
- }

监听EditTextPreference和ListPreference的值修改后,更新描述内容
在fragment的onCreate方法中注册监听器,需要先在fragment中implements SharedPreferences.OnSharedPreferenceChangeListener
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
- }
设置EditTextPreference和ListPreference的值修改后显示正确的描述内容
- @Override
- public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
- Preference preference = findPreference(key);
- if (null != preference) {
- if (!(preference instanceof CheckBoxPreference)) {
- String value = sharedPreferences.getString(preference.getKey(), getString(R.string.pref_color_red_value));
- setupPreferenceSummary(preference, value);
- }
- }
- }
别忘了要在onDestroy方法中取消注册:
- @Override
- public void onDestroy() {
- super.onDestroy();
- getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
- }
注意,我们这里用到了EditTextPreference,因为我这里希望只获取float类型的值,如果用户输入其它类型的值,会在赋值的时候导致类型异常报错,所以我们要在修改Preference值之前先对用户输入的内容进行判断处理。
为了解决这个问题,我们可以在fragment中implements Preference.OnPreferenceChangeListener,然后实现对应的onPreferenceChange方法,onPreferenceChange方法实现如下,如果用户输入我们期待的数据类型,则return true,否则return false:
@Override public boolean onPreferenceChange(Preference preference, Object newValue) { Toast error = Toast.makeText(getContext(), "Please select a number between 0.1 and 3", Toast.LENGTH_SHORT); String sizeKey = getString(R.string.pref_size_key); if (preference.getKey().equals(sizeKey)) { String stringSize = ((String) (newValue)).trim(); if (stringSize.equals("")) stringSize = "1"; try { float size = Float.parseFloat(stringSize); if (size > 3 || size <= 0) { error.show(); return false; } } catch (NumberFormatException nfe) { error.show(); return false; } } return true; }
设置修改Preference前的回调,该监听不需要在退出的时候取消注册,通过对比方法名可以看出,这里是set方法,不是register:
- Preference preference = findPreference(getString(R.string.pref_size_key));
- preference.setOnPreferenceChangeListener(this);
注意,使用PreferenceFragmentCompat需要在application的主题中添加属性,否则在打开引用PreferenceFragmentCompat的页面会报错:
<item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
此外,PreferenceScreen还可以设置偏好类别和通过代码code的方式引入PreferenceScreen而不仅仅是通过xml的方式引入,更多相关内容可以查看官方用户指南链接
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。