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

一、获取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.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, ""));
    }
}

5.2、注册监听

通过SharedPreferences的registerOnSharedPreferenceChangeListener方法注册一个监听器

@Override
public void onResume() {
    super.onResume();
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}

5.3、取消监听

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

@Override
public void onPause() {
    super.onPause();
    getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}

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

5.4、参考

参考地址

六、偏好设置实例

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值