SharedPreferences安卓共享偏好设置,安卓数据本地存储

目录

 

一、获取SharedPreferences实例

1.1、指定名称的SharedPreferences

1.2、获取默认的SharedPreferences

二、编辑和删除数据

2.1、获取编辑器

2.2、赋值

2.3、标记删除所有数据

2.3、提交

三、查看数据

四、静态资源引用

4.1、字符串静态资源引用

4.2、布尔值静态资源引用

五、监听SharedPreferences的数据被修改

5.1、注册监听

5.2、取消监听

六、偏好设置实例

6.1、PreferenceFragmentCompat


一、获取SharedPreferences实例

1.1、指定名称的SharedPreferences

Context.getSharedPreferences(String name, int mode)

由于Activity中已经存在Context的实例,所以在Activity中可以直接通过getSharedPreferences(String, int)获取SharedPreferences的实例

参数说明

name:SharedPreferences存储的文件名,如果name不存在,则会在Editor.commit()后创建

mode:创建模式,值为0或者其他的值,我们一般填0应用内访问就可以了,详情查看

1.2、获取默认的SharedPreferences

PreferenceManager.getDefaultSharedPreferences(Context context)

我这里用的是android.support.v7.preference库,使用的时候需要在App gradle中配置dependencies

如下图所示

 代码如下

implementation 'com.android.support:preference-v7:28.0.0'

二、编辑和删除数据

2.1、获取编辑器

SharedPreferences.edit(),获取SharedPreferences.Editor的实例

2.2、赋值

字符串赋值:putString(String key, String value)

2.3、标记删除所有数据

clear()

2.3、提交

提交有一下两种方式,修改数据完成后需要执行提交的方法才会完成修改

(1)、apply()

(2)、commit()

SharedPreferences.Editor更多的使用方法参考链接

三、查看数据

查看数据是基于SharedPreferences的实例进行操作

如:getString(String key, String defValue)

更多查看方式链接

四、静态资源引用

4.1、字符串静态资源引用

这里用到的key字符串与及其它字符串默认值建议使用引用静态资源的方式赋值,详情参考链接

注意,在使用静态资源赋值到key时,需要设置translatable属性为false,防止国际化等其它原因导致key值被转换,设置如下所示:

<string name="pref_size_key" translatable="false">size</string>

4.2、布尔值静态资源引用

布尔类型的默认值建议也是用资源引用的方式赋值,详情参考链接

五、监听SharedPreferences的数据被修改

5.1、注册监听

通过SharedPreferences的registerOnSharedPreferenceChangeListener方法注册一个监听器,监听数据改变时触发方法

public abstract void registerOnSharedPreferenceChangeListener (SharedPreferences.OnSharedPreferenceChangeListener listener)

比如在Activity中实现接口SharedPreferences.OnSharedPreferenceChangeListener,实现接口的方法onSharedPreferenceChanged,然后在registerOnSharedPreferenceChangeListener方法中传入this即可

比如下面的实现代码:

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
        if (s.equals(getString(R.string.pref_show_bass_key))) {
            mVisualizerView.setShowBass(sharedPreferences.getBoolean(getString(R.string.pref_show_bass_key),getResources().getBoolean(R.bool.pref_show_bass_default)));
        }else if (s.equals(getString(R.string.pref_show_mid_key))) {
            mVisualizerView.setShowMid(sharedPreferences.getBoolean(getString(R.string.pref_show_mid_key),getResources().getBoolean(R.bool.pref_show_mid_default)));
        }else if (s.equals(getString(R.string.pref_show_treble_key))) {
            mVisualizerView.setShowTreble(sharedPreferences.getBoolean(getString(R.string.pref_show_treble_key),getResources().getBoolean(R.bool.pref_show_treble_default)));
        } else if ((s.equals(getString(R.string.pref_color_key)))) {
            mVisualizerView.setColor(getPreferenceColor(sharedPreferences));
        } else if ((s.equals(getString(R.string.pref_size_key)))) {
            mVisualizerView.setMinSizeScale(Float.parseFloat(sharedPreferences.getString(getString(R.string.pref_size_key), getString(R.string.pref_size_default))));
        }
    }

5.2、取消监听

如果注册了监听,则需要在退出的时候取消注册监听:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
    }

需要注意的是,我前面注册的是默认的SharedPreferences,所以取消注册的时候我也是先获取的默认的SharedPreferences。

六、偏好设置实例

6.1、PreferenceFragmentCompat

其实还有对应的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的方式引入,更多相关内容可以查看官方用户指南链接

猜你喜欢

转载自blog.csdn.net/yann02/article/details/94170691