SharedPreferences使用

1.SharedPreferences简介

为了保存软件的设置参数,Android平台为我们提供了一个SharedPreferences接口,它是一个轻量级的存储类,特别适合用于保存软件配置参数。使用SharedPreferences保存数据,其背后是用xml文件存放数据,文件存放在/data/data/<package name>/shared_prefs目录下。

2.获取SharedPreferences对象方法:

  • SharedPreferences pre = Context.getSharedPreferences(String name,int mode);

注:name为本组件的配置文件名(自定义),当这个文件不存在时,直接创建,如果已经存在,则直接使用(如果想要与本应用程序的其他组件共享此配置文件,可以用这个名字来检索到这个配置文件,在这里要特别注意,因为在Android中已经确定了SharedPreferences是以xml形式保存,所以,在填写文件名参数时,不要给定“.xml”后缀,android会自动添加。只要直接写上文件名即可。它会直接被保存在/data/data/<package name>/shared_prefs路径下,它是采用键值对的形式保存参数。当你需要获得某个参数值时,按照参数的键索引即可)。

  • SharedPreferences pre = Activity.getPreferences(int mode);

这个方法默认使用当前类不带包名的类名作为文件的名称。

注:配置文件仅可以被调用的Activity使用。mode为操作模式,默认的模式为0或MODE_PRIVATE,还可以使用MODE_APPEND、MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE。

  • SharedPreferences pre = PreferenceManager.getDefaultSharedPreferences(Context);

注:每个应用都有一个默认的配置文件preferences.xml,使用getDefaultSharedPreferences获取。

3.SharedPreferences使用步骤:

 1)写入数据:
     //步骤1:创建一个SharedPreferences对象
     SharedPreferences sharedPreferences= getSharedPreferences("data",Context.MODE_PRIVATE);
     //步骤2: 实例化SharedPreferences.Editor对象
     SharedPreferences.Editor editor = sharedPreferences.edit();
     //步骤3:将获取过来的值放入文件
     editor.putString("name", “Tom”);
     editor.putInt("age", 28);
     editor.putBoolean("marrid",false);
     //步骤4:提交               
     editor.commit();


 2)读取数据:
     SharedPreferences sharedPreferences= getSharedPreferences("data", Context .MODE_PRIVATE);
     String userId=sharedPreferences.getString("name","");

3)删除指定数据
     editor.remove("name");
     editor.commit();


4)清空数据
     editor.clear();
     editor.commit();

apply 和 commit 的区别

apply:异步执行,没有返回值;
commit:同步执行,有返回值。
如果不考虑结果并且是在主线程执行推荐使用 apply;
需要确保操作成功且有后续操作的话,用 commit()

SharedPreferences 的创建模式

MODE_PRIVATE:默认模式,该模式下创建的文件只能被当前应用或者与该应用具有相同SharedUserID的应用访问。
MODE_WORLD_READABLE:允许其他应用读取这个模式创建的文件。在Android N上使用该模式将抛出SecurityException异常。
MODE_WORLD_WRITEABLE:允许其他应用写入这个模式创建的文件。在Android N上使用该模式将抛出SecurityException异常。
MODE_APPEND:如果文件已经存在了,则在文件的尾部添加数据。
MODE_MULTI_PROCESS:SharedPreferences加载标志,当设置了该标志,则在磁盘上的文件将会被检查是否修改了,尽管SharedPreferences实例已经在该进程中被加载了。(鸡肋,不要用,推荐用ContentProvider)

 

PreferenceActivity和PreferenceFragment.

PreferenceActivity主要针对3.0以前的版本,PreferenceFragment则更为灵活,其实使用方法上面两者大致一样,所以PreferenceActivity就不展开讲解,直接来看PreferenceFragment的使用
一般来说Fragment会要求去关联一个布局的layout, 但是在PreferenceFragment则不需要这样做,我们需要去自定义一个xml加入首选项(首选项就是配置项,官方称为首选项). xml根节点必须是一个PreferenceScreen元素. PreferenceScreen里面的子项都作为一个独立的控件显示在界面里,同时还具备保存属性.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="checkbox_preference"
        android:title="@string/title_checkbox_preference"
        android:summary="@string/summary_checkbox_preference" />
    <ListPreference
        android:key="list_preference"
        android:title="@string/title_list_preference"
        android:summary="@string/summary_list_preference"
        android:entries="@array/entries_list_preference"
        android:entryValues="@array/entryvalues_list_preference"
        android:dialogTitle="@string/dialog_title_list_preference" />
</PreferenceScreen>

显示效果如下

以上只展示了CheckBoxPreference和ListPreference,还有其它很多Preference控件,具体可以查阅官方文档有关Preference的字类.
如果设置项目过多,我们可以进行分类展示,有如下两种方式可以来实现.

使用标题

加入PreferenceCategory的属性可以进行标题的划分.

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

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

        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="@string/summary_checkbox_preference"
            android:title="@string/title_checkbox_preference"/>

    </PreferenceCategory>

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

        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="@string/summary_checkbox_preference"
            android:title="@string/title_checkbox_preference"/>
        <ListPreference
            android:dialogTitle="@string/dialog_title_list_preference"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:key="list_preference"
            android:summary="@string/summary_list_preference"
            android:title="@string/title_list_preference"/>
    </PreferenceCategory>
</PreferenceScreen>

使用子屏幕

使用PreferenceCategory属性可以划分子屏幕

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

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

        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="@string/summary_checkbox_preference"
            android:title="@string/title_checkbox_preference"/>

    </PreferenceCategory>

    <PreferenceScreen
        android:key="button_voicemail_category_key"
        android:title="Voice mail"
        android:persistent="false">

        <CheckBoxPreference
            android:key="checkbox_preference"
            android:summary="@string/summary_checkbox_preference"
            android:title="@string/title_checkbox_preference"/>
        <ListPreference
            android:dialogTitle="@string/dialog_title_list_preference"
            android:entries="@array/entries_list_preference"
            android:entryValues="@array/entryvalues_list_preference"
            android:key="list_preference"
            android:summary="@string/summary_list_preference"
            android:title="@string/title_list_preference"/>
    </PreferenceScreen>
</PreferenceScreen>

配置intent跳转相应的activity

有时候我们的设置项目并不是保存一个配置项,而是去跳转到一个新的画面. 我们可以使用如下配置来使得首选项跳转一个网页

<Preference android:title="@string/prefs_web_page" >
    <intent android:action="android.intent.action.VIEW"
            android:data="http://www.example.com" />
</Preference>

当然你也可以配置显式的intent进行跳转,具体可以参见官方文档.
可以设置默认值给Preference控件

<!-- default value is a boolean -->
<CheckBoxPreference
    android:defaultValue="true"
    ... />

<!-- default value is a string -->
<ListPreference
    android:defaultValue="@string/pref_syncConnectionTypes_default"
    ... />

在进入设置页面可以调用

PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);

对默认值进行初始化应用, 这个接口最常用的地方就是去恢复设置.

使用首选项标头

通常还有种需求是点击一个首选项跳转到另外一个屏幕,当然这个功能也可以通过PreferenceScreen来完成,但是使用PreferenceScreen不能兼容平板的情况就像下面这样

如果要实现这种效果就要使用到hearders

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one" />
    <header
        android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <!-- key/value pairs can be included as arguments for the fragment. -->
        <extra android:name="someKey" android:value="someHeaderValue" />
    </header>
</preference-headers>

android:fragment用来标记点击后跳转的Fragment,extra用来传递参数,可以在Fragment中通过getArguments()来获取传递过来的bundle数据, 这个数据最大的作用就是用来在同一个preference fragment中加载不同的preference xml.

public static class SettingsFragment extends PreferenceFragment {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String settings = getArguments().getString("settings");
        if ("notifications".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_wifi);
        } else if ("sync".equals(settings)) {
            addPreferencesFromResource(R.xml.settings_sync);
        }
    }
}

如果要显示这个标头文件的内容需要去重写onBuildHeaders方法.

public class SettingsActivity extends PreferenceActivity {
    @Override
    public void onBuildHeaders(List<Header> target) {
        loadHeadersFromResource(R.xml.preference_headers, target);
    }
}

preference-headers这个标签只能支持3.0以后的版本,如果要兼容3.0以前的版本需要另外在写个xml作为兼容

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <Preference
        android:title="@string/prefs_category_one"
        android:summary="@string/prefs_summ_category_one"  >
        <intent
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_ONE" />
    </Preference>
    <Preference
        android:title="@string/prefs_category_two"
        android:summary="@string/prefs_summ_category_two" >
        <intent
            android:targetPackage="com.example.prefs"
            android:targetClass="com.example.prefs.SettingsActivity"
            android:action="com.example.prefs.PREFS_TWO" />
    </Preference>
</PreferenceScreen>

再以如下方式加载

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

    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
        // Load the legacy preferences headers
        addPreferencesFromResource(R.xml.preference_headers_legacy);
    }
}

// Called only on Honeycomb and later
@Override
public void onBuildHeaders(List<Header> target) {
   loadHeadersFromResource(R.xml.preference_headers, target);
}

onBuildHeaders这个回调只会在Build.VERSION_CODES.HONEYCOMB(3.0系统)以上的版本调用。
另外我们必须要注意的一点,目前首选项不会再您调用registerOnSharedPreferenceChangeListener()时存储对监听器的强引用。但是,您必须存储对监听器的强引用,否则它将很容易被当作垃圾回收。
上面就是关于如何使用系统提供具有Preference功能的UI控件来打造一个设置界面. 更多详细关于自定义Preference等可以参考官方文档 https://developer.android.com/guide/topics/ui/settings



https://blog.csdn.net/w47_csdn/article/details/51766401

https://www.jianshu.com/p/9a094e4b7eb9

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值