Settings Preference 的理解

2023-05-16

  大纲:

 1、一个简单的Preference例子

2、Preferenece数据的操作

3,Preferenece XML

4,Using Preference Fragments

5,Using Preference Headers

6,读取preference的数据
7,Preference 和SharePreference的联系

 Preference直译为偏好,博友建议翻译为首选项。一些配置数据,一些我们上次点击选择的内容,我们希望在下次应用调起的时候依然有效,无须用户再一次进行配置或选择。Android提供preference这个键值对的方式来处理这种情况,自动保存这些数据,并立时生效,同时Android提供一种类似的layout的方式来进行Prefernce的布局。

一、一个简单的Preferenece例子

步骤1:编写preference XML,在res/xml/下加入我们的preference XML文件,例如名字叫c21preference.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- preference的组织方式有PreferenceScreen和PreferenceCategory,PreferenceCategory是带层次组织关系,在后面的例子体验,而PreferenceScreen就是最平白和基础的方式 -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 有四个基本组建,这个例子学习两个。里面的内容对照图,很容易理解,RingtonePreference是选择铃音,这里给出两个选择,系统默认的铃音和无声 -->
    <CheckBoxPreference android:key="checkbox"
        android:title="CheckBox Preference"
        android:summary="Check it on , check it off"/>
    <RingtonePreference android:key="ringtone"
        android:title="Ringtone Preference"
        android:showDefault="true"
        android:showSilent="true"
        android:summary="Pick a tone, any tone"/>
</PreferenceScreen>

步骤2:在java源代码中调用该xml,生成相应的preference界面

public class Chapter21Test1 extendsPreferenceActivity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.c21preference);
    }
}

和用layout方式一样,代码很简单。和以往界面最大的区别是,我们对checkbox进行选择或者对ringtone进行选择后,这个选择结果是被保留的,当我们退出actitvity后再次进入,上次的选项依然保留,我们重新向模拟器load应用,发现之前的选项仍然存在。我们可以利用preference,而无须人工对数据进行保存和读取,很是方便。

二、getSharedPreferences():可以获取映用级别的preferences(),在这个例子中由于我们封装在同一app中,也可以使用SharePreferences prefs = getSharedPreferences( "com.wei.android.learning_preferences" ,0);其中第一个参数name的格式是<package_name>_preferences;
三、getDefaultSharedPreferences():就是我们例子的方式,通过Android的偏好管理器来获取其所管理的preferences。

二、Preferenece数据的操作

在上面的例子中,preference的数值会被保留,而且可以在其他的activity中读取。如果需要清除数据,可以通过remove()清除某个名字的prefernece,clear()清除所有的preferences。我们可以通过edit()获取preferences的editor,进而进行编辑,修改后,通过commit()将修改值保存。

 

三、Preferenece XML

Preference的XML可以通过PreferenceCategory来进行组织。PreferenceCategory可以将几个组建组合在一起,并加上标题。我们依然用前面的xml例子,通过PreferenceCategory来进行组织,如下:和之前的例子比较,将chekcbox和rintong组织成为一个category,并加上了"simple Preferences"的标题。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
       <PreferenceCategory android:title="Simple Preferences">
            <CheckBoxPreference android:key="checkbox" ..../>
            <RingtonePreference android:key="ringtone" ... />
       </PreferenceCategory>
</PreferenceScreen>

PreferenceCategory也可以嵌套PreferenceScreen,PreferenceScreen中的内容,将通过另一屏来显示,我们在上面例子后面添加一个嵌套了PreferenceScreen的PreferenceCategory。整个PreferenceScreen作为一个组件出现,点击后新的一屏,由入PreferenceScreen定义。通过这个关系,我们可以组织自己的preference架构。

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
       <PreferenceCategory android:title="Simple Preferences">
            <CheckBoxPreference android:key="checkbox" ..../>
            <RingtonePreference android:key="ringtone" ... />
       </PreferenceCategory>
       <PreferenceCategory android:title="Detail Screens">
           <PreferenceScreen android:title="Detail"
               android:summary="Addtional preference help in another page">
               <CheckBoxPreference android:key="checkbox2"
                   android:title="Another Checkbox"
                   android:summary="On or Off, It's a problem...."/>
           </PreferenceScreen>
       </PreferenceCategory>
</PreferenceScreen>

 

也可以设置内层PreferenceScreen(任一项均可)的Intent属性,设置点击PreferenceScreen时跳com.android.phone.SelectSimCard页面。如:

<PreferenceScreen android:key="config_sub"
    android:title="@string/sel_sub_title" android:summary="@string/sel_sub_summary"
    android:persistent="false">
    <intent android:action="android.intent.action.MAIN"
        android:targetPackage="com.android.phone" android:targetClass="com.android.phone.SelectSimCard" />
</PreferenceScreen>
还可以这样设置:


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

它会新增一项,标题为android:title中设置的值,当你点击这项时,它会跳到 a web browser.

在前面的例子中我们使用了CheckBox和Ringtong,在下面的例子,我们实验另外的两个组建EditText和List,这两种都是已弹框的方式。在上面的例子我们继续增加内容

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen ...>
       ......     
       <PreferenceCategory android:title="Other Preferences">
           <EditTextPreference android:key="text"
               android:title="Text Entry Dialog"
               android:summary="Click to pop up a field for entry"
               android:dialogTitle="Enter something useful"/>
           <ListPreference android:key="list"
               android:title="Selection Dialog"
               android:summary="Click to pop yo a list for select"
               android:entries="@array/cities"
               android:entryValues="@array/airport_codes"
               android:dialogTitle="Choose a City"/>
       </PreferenceCategory>
</PreferenceScreen>

在list中由两个引用@array/cities和@array/airport_codes,我们在资源文件中定义此两array。内容如下:
<resource>
     <string-array>
        <item>Pittsburgh</item>
        <item>Allentown/Bethlehem</item>
        <item>Erie</item>
        ... ...
    </string-array>
    <string-array name="airport_codes">
        <item>PHL</item>
        <item>PIT</item>
        <item>ABE</item>
        ... ...
    </string-array>
</resources>

运行结果如右图所示。对于EditText,键值对保存的值是String,即用户在输入框中输入的内容。List的情况稍微复杂一些,在设置ListPreference的属性有一个entires,这是在List显示给用户看的内容,如果我们去获取preference的值,在这个例子为prefs.getString("list", "<unset>");,则返回在entryValues对应的数值,例如我们选择了第一个item:Pittsburgh,则获取的值为PHL。entries和entryValues是一一对应的。

对于EditText,键值对保存的值是String (The saved value is a boolean ),即用户在输入框中输入的内容。 CheckBox保存的值为Boolean型,选中即为true.List保存的值类型可以多种( The saved value can be any one of the supported value types (listed above Boolean,Float, Int ,Long, String, StringSet)List的情况稍微复杂一些,在设置ListPreference的属性有一个entires,这是在List显示给用户看的内容,如果我们去获取preference的值,在这个例子为prefs.getString("list", "<unset>");,则返回在entryValues对应的数值,例如我们选择了第一个item:Pittsburgh,则获取的值为PHL。entries和entryValues是一一对应的。

四、Using Preference Fragments
如果你使用的是android3.0或更高的版本,建议使用PreferenceFragment.

If you're developing for Android 3.0 (API level 11) and higher, you should use a PreferenceFragmentto display your list of 
Preference objects. You can add a PreferenceFragment to any activity—you don't need to usePreferenceActivity

Fragments provide a more flexible architecture for your application, compared to using activities alone, no matter what kind of activity you're building. As such, we suggest you use PreferenceFragmentto control the display of your settings instead of PreferenceActivitywhen possible.Your implementation of PreferenceFragmentcan be as simple as defining the onCreate() method to load a preferences file with addPreferencesFromResource()
. For example:

 


public static class SettingsFragment extends PreferenceFragment {      @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);            // Load the preferences from an XML resource          addPreferencesFromResource(R.xml.preferences);      }      ...  }  

You can then add this fragment to an Activity just as you would for any other Fragment. For example:


public class SettingsActivity extends Activity {      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);            // Display the fragment as the main content.          getFragmentManager().beginTransaction()                  .replace(android.R.id.content, new SettingsFragment())                  .commit();      }  }  

Note: A PreferenceFragment doesn't have a its own Context object. If you need a Contextobject, you can call getActivity(). However, be careful to call getActivity() only when the fragment is attached to an activity. When the fragment is not yet attached, or was detached during the end of its lifecycle,getActivity() will return null.(这段话暂不去理解---)

 

五、Using Preference Headers

怎样去使用preference header呢?

第一步:创建一个preference header文件

以下是preferenceheader.xml

<?xml version="1.0" encoding="utf-8"?>
<preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
    <header
        android:fragment="eng2.app2.settings.SettingsFragment"   
        android:title="The first header"
        android:summary="The first header summary" />                        
      <header
        android:fragment="eng2.app2.settings.SettingsFragment"
        android:title="The second header"
        android:summary="The second header summary" />
</preference-headers>

Settings Preference 的理解 - Corio - 谭晓雅


为了方便,我这里两个fragment都是使用同一个类

第二步:创建一个继承了PreferenceFragment的类。

public  class SettingsFragment extends PreferenceFragment{

 @Override
 public void onCreate(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onCreate(savedInstanceState);
  addPreferencesFromResource(R.xml.preferences);
 }

}

这个类实现的功能就是实现R.xml.preferences的页面

以下是R.xml.preferences

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    <CheckBoxPreference
        android:key="checkbox"
        android:title="CheckBox Preference"
        android:summary="Check it on , check it off"/>   

       <ListPreference
        android:key="list"
        android:title="ListPreference"
        android:dialogTitle="dialog title"
        android:entries="@array/cities"
        android:entryValues="@array/airport_codes"
        android:defaultValue="default value">
        <intent android:action="android.intent.action.VIEW"
            android:data="http://www.example.com" />
    </ListPreference>
    <PreferenceCategory
       android:title="Categoty"  >
         <RingtonePreference android:key="ringtone"
        android:title="Ringtone Preference"
        android:showDefault="true"
        android:showSilent="true"
        android:summary="Pick a tone, any tone"
        />
         <PreferenceScreen
             android:title="preferenceScreen"
             >
             <Preference  android:title="Preference">
                <intent android:action="android.intent.action.VIEW"
                     android:data="http://www.example.com" />
             </Preference>
              <EditTextPreference
        android:key="edit"
        android:title="EditTextPreference"
        android:defaultValue="default value"
        android:summary="summary"
        />
         </PreferenceScreen>
        
    </PreferenceCategory>
  
</PreferenceScreen>

如图:

 

   第三步:就是创建一个继承了PreferenceActivity的类,在这个类实现 public void onBuildHeaders(List<Header> target)

public class SetttingsActivity extends PreferenceActivity {

 @Override
 public void onBuildHeaders(List<Header> target) {
  // TODO Auto-generated method stub
  super.onBuildHeaders(target);
  loadHeadersFromResource(R.xml.preferencesheader,target);
 }
 }

注意这个类没必要写onCreate().同时这个类要作为android启动类。   

查看FileExplore下data/data/xxxpackage/shared-pres系统自动建立了对应了SharedPreference文件。preference中的键值对是存储在SharedPreference文件中的。

 

六、读取preference的数据

既然在preference的界面中可以保留数据,我们也希望能够读出数据,以便这些数据可以用在其他的activity中。如果另一个activity和这些数据关联,而且希望能够实时进行同步,在onResume()中对preference保留的数据进行读取,而后进行相关的更新。

首先要获取preferences,然后通过键值对的获取方式根据key获取数值,在xml中checkbox的key为“checkbox”,值的类型为布尔值,而rintong的值为String,例如:

    protected void onResume() { //在另一个Activity中
        super.onResume();
        SharedPreferences prefs =PreferenceManager.getDefaultSharedPreferences(this) ;
        System.out.println(new Boolean(prefs.getBoolean("checkbox",false)).toString());//false表示没有查到checkbox这个key的返回值
        System.out.println(prefs.getString("ringtone","<unset>"));//<unset>表示没有查到ringtong这个key的返回值
    }

获取preferences可以通过三种方式:
一、getPreferences():可以获取同一activity中的preference;
二、getSharedPreferences():可以获取映用级别的preferences(),在这个例子中由于我们封装在同一app中,也可以使用SharePreferences prefs = getSharedPreferences( "com.wei.android.learning_preferences" ,0);其中第一个参数name的格式是<package_name>_preferences;

三、getDefaultSharedPreferences():就是我们例子的方式,通过Android的偏好管理器来获取其所管理的preferences。

七、Preference 和SharePreference的联系

Each Preference you add has a corresponding key-value pair that the system uses to save the setting in a default 

SharedPreferences file for your app's settings. When the user changes a setting, the system updates the corresponding value in the SharedPreferences file for you. The only time you should directly interact with the associated SharedPreferences
 file is when you need to read the value in order to determine your app's behavior based on the user's setting.
  preference是用来保存键值对的,而系统把这些键值对保存在对应的SharedPreference文件中(每一个包对应一个

SharedPreference文件)。当用户改变设置时,系统就会更新SharedPreference文件中对应的值。你需要跟SharedPreference直接打交道的时候是你需要根据用户的设置读取值来决定app的行为。

 以下是本人写的preference较综合的程序。

 package eng2.app2.example.testsettings;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.view.Menu;
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener{
  SharedPreferences preferences;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
         preferences=PreferenceManager.getDefaultSharedPreferences(this);
    }
    @Override
 protected void onResume() {
  // TODO Auto-generated method stub
     System.out.println("onResume---");
  super.onResume();
//根据key到sharedPreference中去查找相对应的preference,如果找到了,返回找到的值;如果没找到,则返回第二个参数的值。
  System.out.println("1---"+preferences.getBoolean("checkbox", false));
        System.out.println("2---"+preferences.getString("edit", "Not Found"));
        System.out.println("3---"+preferences.getString("list", "Not Found"));
        preferences.registerOnSharedPreferenceChangeListener(this);
        System.out.println("registered---");
        SharedPreferences.Editor editor=preferences.edit();
        editor.putString("list", "ABE");//如果改变了sharePres中的值,监听事件去处理。如果list中本来就是ABE则监听事件不处理
        editor.putBoolean("checkbox", true);//依上
        editor.commit();
        System.out.println("21---"+preferences.getBoolean("checkbox", false));
        System.out.println("22---"+preferences.getString("edit", "Not Found"));
        System.out.println("23---"+preferences.getString("list", "Not Found"));    
 }
 @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_settings, menu);
        return true;
    }
 @Override
 protected void onPause() {
  // TODO Auto-generated method stub
  System.out.println("onPause---");
  preferences.unregisterOnSharedPreferenceChangeListener(this);
  super.onPause();
 }
 @Override
 public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
   String key) {
  // TODO Auto-generated method stub
  System.out.println("onSharedPreferenceChanged---");
 }

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Settings Preference 的理解 的相关文章

随机推荐

  • Windows使用经验收集

    19 最快的编辑任意网页代码 打开浏览器 xff0c 浏览一个网页 xff0c 按下F12打开开发人员工具 xff0c 然后点击console xff0c 也就是控制台 xff0c 输入 document body contentEdita
  • 如何提高自己的编程能力

    原帖地址 xff1a http www blogjava net xvridan archive 2007 02 17 100143 html 1 扎实的基础 数据结构 离散数学 编译原理 xff0c 这些是所有计算机科学的基础 xff0c
  • 排序算法学习

    61 61 61 冒泡排序 61 61 61 JAVA语言实现 学习冒泡排序 冒泡排序 xff08 Bubble Sort xff0c 台湾译为 xff1a 泡沫排序或气泡排序 xff09 是一种简单的排序算法 它重复地走访过要排序的数列
  • Android的Activity屏幕切换动画(二)-左右滑动深入与实战

    原帖 xff1a http www oschina net question 97118 34523 上一篇文章讲了 Android的左右滑动切换 xff0c 实现过程是非常简单 xff0c 一些新手可能会向深入了了解Activity切换的
  • Android 第三方 UI 库 GreenDroid 使用方法

    原帖地址 xff1a http www acwind net blog p 61 1297 一直觉得 Android SDK 本身提供的界面 UI 库实在是太难看了 xff0c 而且提供的功能也总是这里那里很多缺憾 所以一直在关注各种第三方
  • android视野慢慢开阔

    1 umeng 友盟移动开发者服务平台 http www umeng com 原来是分析用户的 xff0c 长见识了 友盟统计分析3 0 用更精细的数据读懂用户 服务超过30 000开发者 100 000款APP xff0c 日启动次数15
  • HTC G7 desire刷机和小米4刷原生安卓

    步骤 1 root 2 安装recovery recovery img文件 http down10 zol com cn shouji recovery clockwork 2 5 0 1 bravo slcd img reflash文件
  • java一些疑问的求证和遇到的问题

    100 关于byte array 有一个字符串s xff0c 输出字符对应的unicode十进制和十六进制 getBytes 貌似获取每个字符的8位二进制的字节 xff1b 输出字节的十六进制形式的字符串验证后确实是 String s 61
  • Java基础

    Java语言的一些基础知识 xff0c 需要常记在心 xff0c 但是好记性不如烂笔头 就记在这吧 final 修饰的变量不能被赋值 xff0c 可以在定义的同时赋值 final 修饰的方法可以被继承 xff0c 不能被重写override
  • Java EE学习

    遇见的问题 servlet访问出现404 xff0c jsp正常访问 java jdk1 8 eclipse2018 12 4 10 0 Dynamic web module version 4 0 Tomcat9 0 经过一番搜索 xff
  • 手把手教你Asp.net三层架构

    首先简单介绍下三层乃至多层架构 xff08 高手跳过 xff09 xff1a BLL 就是business Logic laywer xff08 业务逻辑层 xff09 他只负责向数据提供者也就是DAL调用数据 然后传递给客户程序也就是UI
  • 深奥的补码

    上学的时候汇编语言中有原码 反码 补码 考试的时候经常考 xff0c 比较好的办法就是记住他们的转换规则 xff0c 但是虽然记住转换规则 xff0c 考试也考不差 xff0c 心头却始终有朵乌云挥之不去 xff0c 令人异常纠结 xff0
  • 详解Android Intent

    一 Intent 作用 Intent被译作意图 xff0c 其实还是很能传神的 xff0c Intent期望做到的 xff0c 就是把实现者和调用者完全解耦 xff0c 调用者专心将以意图描述清晰 xff0c 发送出去 xff0c 就可以梦
  • 如何检索Android设备的唯一ID

    Android的开发者在一些特定情况下都需要知道手机中的唯一设备ID 关于本文档 Android 的开发者在一些特定情况下都需要知道手机中的唯一设备 ID 例如 xff0c 跟踪应用程序的安装 xff0c 生成用于复制保护的 DRM 时需要
  • centos6 yum源失效解决方法

    今天看到服务器提示有漏洞需要更新 xff0c 在执行更新命令的时候一直报错 xff0c 因为CentOS 6操作系统版本结束了生命周期 xff08 EOL xff09 xff0c Linux社区已不再维护该操作系统版本 导致不能正常更新 x
  • 安卓使用NavHostFragment时,如何取消按返回键Fragment层层返回效果,去除层层返回

    问题现象 xff1a 在安卓中使用NavHostFragment搭配Fragment做APP主页导航时 xff0c 如果在几个Fragment来回切换了很多次 xff0c 当按返回键想退出app时 xff0c 会造成首先要在Fragment
  • 产品化思维

    1 1 产品的本质 能够供给市场 xff0c 被人们使用和消费 xff0c 并能满足人们某种需求的任何东西 xff0c 包括有形的物品 无形的服务 组织 观念或它们的组合 定义 xff1a 市场是提供给买卖双方交易的平台 xff0c 而人在
  • C和C++的区别?

    C和C 43 43 的区别为 xff1a 结构不同 设计不同 库函数不同 一 结构不同 1 C语言 xff1a C语言结构只有成员变量 xff0c 而没有成员方法 2 C 43 43 xff1a C 43 43 结构中可以有自己的成员变量和
  • 自定义生成公众号二维码,用于小票打印机使用

    近期因项目需求 xff0c 需要将微信公众号二维码打印在小票上 xff0c 小票打印机不支持直接打印图片 xff0c 现在找到一个利用链接来生成自己的微信公众号二维码 xff0c 链接如下 xff1a https mp weixin qq
  • Settings Preference 的理解

    大纲 xff1a 1 一个简单的Preference例子 2 Preferenece数据的操作 3 xff0c Preferenece XML 4 xff0c Using Preference Fragments 5 xff0c Using