目录(?)[-]

  1. 例子1ListPreference小例子
    1. 定义一个preferences XML文件
    2. 继承PreferenceActivity
    3. 用户定制偏好的读取
      1. 第一次运行时设置缺省值
    4. 设置Category

Adnroid提供Preferences framework,用户可定制化应用,可用来保存信息和状态。在Android学习笔记(四十):Preference的使用中我已经对preferences有所了解。在Android 3.0,随着对平板的支出,preferences有不少的变化。

例子1:ListPreference小例子

我们先同一个简单的例子来复习。机票的显示缺省是按最低价格,但是用户可以选择自己希望的排序方式,并设为默认排序。在这个例子中,使用API level 11之前的方法,在实现方面会更为简单,主要是为了更好了解什么是preference。Android提供的完整的prefrences framework,包括通过xml定义、显示设置,可保留用户选择项。

例子执行如图,左图称为preference screen为定制设定的选项,点击,展开右图,是一个list preference,以带有radio button的对话框方式呈现,当用户选择某个配置,将马上被保存,并关闭对话框,用户重新打开,即时是activity关闭后重新打开,也可得到之前定制配置。例子的实现分为两个步骤:

1、定义一个preferences XML文件

res/xml下,我们定义名为fightoptions.xml的文件,如下。合理的属性值应该采用@string/xxxx的方式,但是为了很好的例子对应,我们直接赋值。

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="flight_option_preference"   按:可以通过key来获取preference,类似于view的android:id 
    android:title="My Preferences"                 按:对于最top的PreferenceScreen,此为Activity的title 
    android:summary="设置航线排序选项"> 
    <ListPreference android:key="selected_flight_sort_option"   按:可以通过key来获取preference 
        android:title="Flight Options"               
        android:summary="Set Search Options" 
        android:entries="@array/flight_sort_options"                    按:list的内容
        android:entryValues="@array/flight_sort_options_values" 按:list各内容对应的value
        android:dialogTitle="Choose Flight Options" 
        android:defaultValue="1"/>  <!-- 对应为entryValues的值,缺省1,即缺省为Number of Stops。 --> 
</PreferenceScreen>

其中有两个数据,我们在res/values/array.xml文件中定义,具体如下:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string-array name="flight_sort_options"> 
        <item>Total Cost</item> 
        <item>Number of Stops</item> 
        <item>AirLine</item> 
    </string-array> 
    <string-array name="flight_sort_options_values"> 
        <item>0</item> 
        <item>1</item> 
        <item>2</item> 
    </string-array> 
</resources>

这两个数组,分别是list preference的entries和entry value,前者是用于显示给用户,后者是用于在设备中保存。本例选取了数组的需要做为entry value。通过android:defatulvalue设置缺省的entry value,如果我们不设置,则取值为null,这显然是不合适。

Preferences保存在设备的/data/data/<package-name>/shared_prefs/<package-name>_preferences.xml文件中,可通过DDMS的文件浏览器查看(对于真实设备,该文件不能读,模拟器上的可以)。

我们通过DDMS的文件浏览器将其导出,如下:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?> 
<map> 
    <string name="selected_flight_sort_option">1</string> 
</map>

保存了list preferences的key和用户选择的entry value。分开entry和entry value是有意义的,开发者可以重新定义entry的描述,或者增加数组的长度,只要维持原有entry value不变,升级后preference仍然有效。一般,我们会在res/vaule/中设置string的值,方便适应不同语言版本,但是要注意key的值不应该有多个。

2、继承PreferenceActivity

public class FightListPreferenceActivity extends PreferenceActivity{ 
    @SuppressWarnings("deprecation") 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);  
        // 将xml定义加载为preferences 
        addPreferencesFromResource(R.xml.fightoptions);
          
        // 以下仅用于了解xml各属性的含义,并读取属性 
        Preference p = findPreference("flight_option_preference"); //通过key来获取preference
        showInfo("p = " + p); 
        showInfo("summary: " + p.getSummary()); 
        showInfo("title: " + p.getTitle());  
         
        ListPreference lp = (ListPreference)findPreference("selected_flight_sort_option");
        showInfo("lp = " + lp); 
        showInfo("entry = " + lp.getEntry()); 
        showInfo("value = " + lp.getValue());          
    } 
    
    private void showInfo(String s){ 
        Log.d(getLocalClassName(),s); 
    } 
}

3、用户定制偏好的读取

用户设置了preferences,应用的其他activity可以读取,应用关闭后,重新启动也能读取相应的配置。在MainActivity中通过OptionsMenu触发FightListPreferenceActivity,我们在MainActivity中提供读取preferences的方法,如下:

private void getPreferenceCfg(){  
     //通过preferences管理器获取本应用的preferences。参数this将使用本package的名字来寻找保存文件。  
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 
    //根据preferences 的key获取entity value,并给出缺省值。由于应用第一次运行时,没有保存的preference文件,如果不使用缺省值,则返回null。在这里,我们直接指定缺省值为“1”,这只是为了例子简单的便捷方式。实际上,我们应该在res/values/下设置我们的缺省值,除了可在preference的xml中引用,还可以直接在此设定缺省值。同一个值不要在多处进行赋值是编程的基本原则之一。  
    String option = prefs.getString("
selected_flight_sort_option", "1"); 
    //通过entity value获取entity的内容 
    String[] optionText = getResources().getStringArray(R.array.flight_sort_options); 
    showInfo("option = " + option + ",select : " + optionText[Integer.parseInt(option)]);
}

另一个获取share prefs的方式如下,第一个参数是帮助查找存储文件,一般可以用应用的报名,第二个参数是mode。可以通过这种方式获取其他应用的preferences。本例,缺省模式为MODE_PRIVATE,对于模拟器,存储文件的读写权限比较高,即使在MODE_PRIVATE模式下,跨应用可以读取。一般我们不使用这种方式,但是如果在同一设备上,有多个用户,可以采用第二种方式,区分开不同用户的定制的偏好,但就目前很少有这种情况。

SharedPreferences prefs = getSharedPreferences("cn.wei.flowingflying.propreferences", 0);

第一次运行时设置缺省值

如果设置项很多,每项在代码中都设置缺省值,推荐的方式如下。在应用第一次运行时,从preference的xml中获取缺省值,并生成保存文件,如果已经有一个SharedPrefferences对象,也会进行更新之,即下面代码中头L3和L4可以互换。即时getString中将缺省值设置为null,也会根据配置读到缺省值。非第一运行,不会改动现有保存值。

protected void onCreate(Bundle savedInstanceState) { 
    … … 
    PreferenceManager.setDefaultValues(this, R.xml.fightoptions, false); 
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 
    String option = prefs.getString("selected_flight_sort_option",null); 
    showInfo("option = " + option ); 
}

执行setDefaultValues()后,即时没有运行PreferenceActivity,系统会根据缺省配置,生成保存文件,如下图。此外还有_has_set_default_values.xml用于表明是通过缺省值创建的。setDefaultValues()的第三个参数,我的试验是在Android 4.4的版本中,无论true或者false,并不会有什么影响,设置true,并不会在已有保存文件的情况下,将其重置为缺省值。

另一个获取share prefs的方式如下,第一个参数是帮助查找存储文件,一般可以用应用的报名,第二个参数是mode。可以通过这种方式获取其他应用的preferences。本例,缺省模式为MODE_PRIVATE,对于模拟器,存储文件的读写权限比较高,即使在MODE_PRIVATE模式下,跨应用可以读取。一般我们不使用这种方式,但是如果在同一设备上,有多个用户,可以采用第二种方式,区分开不同用户的定制的偏好,但就目前很少有这种情况。

SharedPreferences prefs = getSharedPreferences("cn.wei.flowingflying.propreferences", 0);

4、设置Category

Preference可被其他应用获取,PreferenceActivity也可被intent唤起,我们可以设置activity的类型,例如:

<activity android:name=".FightListPreferenceActivity" android:label="@string/test_list_preferences" >
    <intent-filter> 
        <action android:name="cn.wei.flowingflying.propreferences.intent.action.FightPreferences" />
        <category android:name="android.intent.category.PREFERENCE"/>
    </intent-filter> 
</activity>

本博文涉及的例子代码,可以在Pro Android学习:Preference(首选项)小例子中下载。

相关链接: 我的Android开发相关文章

【转】 Pro Android学习笔记(五七):Preferences(1):ListPreference的更多相关文章

  1. 【转】 Pro Android学习笔记(七五):HTTP服务(9):DownloadManager

    目录(?)[-] 小例子 保存在哪里下载文件信息设置和读取 查看下载状态和取消下载 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csd ...

  2. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  3. 【转】 Pro Android学习笔记(七九):服务(4):远程服务的实现

    目录(?)[-] 远程服务的实现小例子 对外开放远程服务的接口 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flow ...

  4. 【转】 Pro Android学习笔记(七六):服务(1):local和remote

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.net/flowingflying/ Android提供服务,服务是运行在后台的 ...

  5. 【转】 Pro Android学习笔记(七四):HTTP服务(8):使用后台线程AsyncTask

    目录(?)[-] 5秒超时异常 AsyncTask 实现AsyncTask抽象类 对AsyncTask的调用 在哪里运行 其他重要method 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注 ...

  6. 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP/JSON/XML、异常

    目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...

  7. 【转】 Pro Android学习笔记(七二):HTTP服务(6):HttpURLConnection

    目录(?)[-] Http Get的使用方式 基础小例子 Cookie的使用 重定向 HTTP POST的小例子 基础小例子 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载 ...

  8. 【转】Pro Android学习笔记(七):了解Content Provider(下上)

    我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...

  9. 【转】 Pro Android学习笔记(七三):HTTP服务(7):AndroidHttpClient

    文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog.csdn.net/flowingflying/ 不知道此文是否是这个系列中最短的一篇.我们 ...

  10. 【转】 Pro Android学习笔记(六七):HTTP服务(1):HTTP GET

    目录(?)[-] HTTP GET小例子 简单小例子 出现异常NetworkOnMainThreadException 通过StrictMode进行处理 URL带键值对 Andriod应用可利用ser ...

随机推荐

  1. 【译】StackOverflow——Java 中的 finally 代码块是否总会被执行?

    问题 有一个 try/catch 代码块,其中包含一个打印语句.finally代码块总会被调用么? 示例: try { something(); return success; } catch (Ex ...

  2. 我的Java开发学习之旅------>Java 格式化类(java.util.Formatter)基本用法

    本文参考: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html http://www.blogjava.net/ ...

  3. PAT 1064. 朋友数(20)

    如果两个整数各位数字的和是一样的,则被称为是“朋友数”,而那个公共的和就是它们的“朋友证号”.例如123和51就是朋友数,因为1+2+3 = 5+1 = 6,而6就是它们的朋友证号.给定一些整数,要求 ...

  4. 使用oracle10g官方文档找到监听文件(listener.ora)的模板

    ***********************************************声明*************************************************** ...

  5. vim中设置tab的长度的方法

    linux下使用vim编程是比較常见的事情,但vim默认的tab是8个空格.但一般的编辑器是4个空格,所以希望改动下.详细方法例如以下:1. 创建文件名称为 .vimrc 的系统文件首先切换到用户根文 ...

  6. mathjax

    MathJax.Hub.Typeset() method. This will cause the preprocessors (if any were loaded) to run over the ...

  7. [GUI] QT事件与X11的关系

    做了一段时间linux下与QT事件相关的工作,经常会遇到X11,总是苦于无法完全理解其与linux以及QT事件之间的关系,所以用两篇文章来简单总结下linux中的图形管理和QT事件与X11的关系. & ...

  8. 狄利克雷卷积&莫比乌斯反演

    昨天刚说完不搞数论了,刚看到一个\(gcd\)的题目dalao用这个做了,虽然比正解麻烦,还是打算学一学了 数论函数: 数论函数的定义: 数论函数亦称算术函数,一类重要的函数,指定义在正整数集上的实值 ...

  9. windows8.1下安装msi文件报错

    新安装了win8.1系统体验体验,可是安装msi文件的软件报internal error2502和2503错误,可以换一种安装方式. 不是直接点开安装,如图所示打开命令提示符: 使用msiexec / ...

  10. js 判断滚动条的滚动方向

    以下代码实现判断页面的滚动条的滚动方向: var sign = 80;//定义默认的向上滚与向下滚的边界 window.onscroll = window.onresize = function(){ ...