这期内容当中小编将会给大家带来有关如何理解Android首选项框架ListPreference,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
探索首选项框架
在深入探讨Android的***项框架之前,首先构想一个需要使用***项的场景,然后分析如何实现这一场景。假设你正在编写一个应用程序,它提供了一个搜索飞机航班的工具。而且,假设该应用程序的默认设置是根据机票价格由低到高的顺序显示航班,但用户可以首选将项设置为始终根据最少停站数或特定航线来航班。如何实现这一场景?
ListPreference
显然,必须为用户提供UI 来查看排序选项列表。该列表将包含每个选项的单选按钮,而且默认(或当前)选项应该被预先选中。要使用Android***项框架解决此问题,所做的工作非常之少。首先,创建***项XML文件来描述***项,然后使用预先构建的活动类,该类知道如何显示和持久化***项,下面是我们的***项XML文件flightoptions.xml 。
Xml代码
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:key="flight_option_preference" android:title="@string/prefTitle" android:summary="@string/prefSummary"> <ListPreference android:key="@string/selected_flight_sort_option" android:title="@string/listTitle" android:summary="@string/listSummary" android:entries="@array/flight_sort_options" android:entryValues="@array/flight_sort_options_values" android:dialogTitle="@string/dialogTitle" android:defaultValue="@string/flight_sort_option_default_value"/> </PreferenceScreen>
上边说了我们还需要一个Activity类FlightPreferenceActivity,下面使我们的Activity类。这个Activity类继承了PreferenceActivity 代码如下:
Java代码
package xiaohang.zhimeng; import android.os.Bundle; import android.preference.PreferenceActivity; public class FlightPreferenceActivity extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.flightoptions); } }
上面的代码清单,包含了一个表示航班选项示例的***项设置的XML片段。该包含了一个活动类,也就是我们的FlightPreferenceActivity 这个类主要用于加载我们的XML 文件。首先看一下XML。Android提供了一种端到端得***项框架。这意味着,该框架支持定义***项,想用户显示设置,以及将用户选择持久化到数据库存储中。 在/res/xml/目录下的XML文件中定义***项。要向用户显示***项,编写一个活动类来扩展预定义的 Android类 android.preference.PreferenceActivity,然后使用 addPreferencesFromResource()方法将资源添加到活动的资源集合中。该框架会负责剩余操作(现实和持久化)。
在本航班场景中,在/res/xml/目录下创建文件 flightoptions.xml。然后创建活动类FlightPreferenceActivity, 它扩展了 android.preference.PreferenceActivity类。接下来调用addPreferencesFromResource() 传入R.xml.flightoptions。请注意,***项资源XML指向多个字符串资源。为了确保正确编译,需要向项目中添加多个字符串资源 (我们稍后介绍)。现在先看一下 上面得代码清单会生成什么样子的UI.
上边有两个视图。左边的视图称为***项屏幕,右边的UI是一个列表***项。当用户选择 Flight Options时, Choose Flight Options视图将以模态对话框的形式出现,其中包含每个选项的单选按钮。用户选择一个选项之后,将立即该选项并关闭视图。当用户返回选项屏幕时,视图将反映前面保存的选择。
前面已提到,***项XML 文件和相关的活动类,从上边我们可以看到 我们在XML文件中定义了一个PreferenceScreen ,然后创建ListPreference作为子屏幕。对于 PreferenceScreen,设置了3个属性: key、title和 summary。 key 是一个字符串,可用于以编程的方式表示项 (类似于使用 android:id的方式);title 是屏幕的标题 (My Preferences) ; summary是对屏幕用途的描述。对于列表***项,设置 key、title和 summary,以及 entries、entryValues、dialogTitle和defaultValue特性。下表总结了这些特性。
特性 | 说明 |
android:key | 选项的名称或键(比如selected_flight_sort_option) |
android:title | 选项的标题 |
android:summary | 选项的简短摘要 |
android:entries | 可将选项设置成列表项的文本 |
android:entryValues | 定义每个列表项的值。注意:每个列表项有一些文本和 一 个 值。 文本由entries定义,值由entryValues定义。 |
android:dialogTitle | 对话框的标题,在视图显示为模态对话框时使用 |
android:defaultValue | 项列表中选项的默认值 |
为了使我们的例子能够正常运行,我们还需要添加如下文件。
Xml代码
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="flight_sort_options"> <item>Total Cost</item> <item># 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>
此文件大家一看就知道是 定义我们选项的显示的文本,和对应的值。这个XML 文件的名字是 arrays.xml 此文件应该放在 /res/values/arrays.xml
当然不能少了我们的strings.xml
Xml代码
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, FlightPreferenceActivity!</string> <string name="app_name">Preference_Demo</string> <string name="prefTitle">My Preferences</string> <string name="prefSummary">Set Flight Option Preferences</string> <string name="flight_sort_option_default_value">1</string> <string name="dialogTitle">Choose Flight Options</string> <string name="listSummary">Set Search Options</string> <string name="listTitle">Flight Options</string> <string name="selected_flight_sort_option">selected_flight_sort_option</string> <string name="menu_prefs_title">Settings</string> <string name="menu_quit_title">Quit</string> </resources>
刚才上边说到我们有一个***项视图,就是那个FlightPreferenceActivity ,在这
这个例子中我们是通过一个菜单跳转到我们的***项视图的。就是我们有一个MainActivity 这个MainActivity有一个菜单叫Settings当我们点击这个菜单的时候就会跳转到我们的***项视图了,然后我们修改***项的内容 当我们再一次回到 MainActivity 的时候就会看到我们修改后的 文本和值,我们通过一个TextView来显示
我们还是来看一下效果吧。
下面这个XML文件就是用来定义我们 这个菜单的,此文件的目录在 /res/menu/mainmenu.xml
Xml代码
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_prefs" android:title="@string/menu_prefs_title" /> <item android:id="@+id/menu_quit" android:title="@string/menu_quit_title" /> </menu>
也比较简单了。
在接下来就是我们的布局文件main.xml了
Xml代码
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/text1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
只有一个TextView 主要用来显示我们修改***项之后的文本和值。
有了main.xml自然少不了MainActivity了,下面使我们的MainActivity类
Java代码
package xiaohang.zhimeng; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.widget.TextView; public class MainActivity extends Activity{ private TextView tv = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); tv = (TextView)findViewById(R.id.text1); setOptionText(); } //创建菜单,这个菜单我们在XML文件中定义 这里加载进来就OK @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); //加载我们的菜单文件 inflater.inflate(R.menu.mainmenu, menu); return true; } //菜单选项事件 @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == R.id.menu_prefs) { //当我们点击 Settings 菜单的时候就会跳转到我们的 ***项视图,也就是我们的 FlightPreferenceActivity Intent intent = new Intent().setClass(this, xiaohang.zhimeng.FlightPreferenceActivity.class); //因为我们要接收上一个Activity 就是我们的***项视图 返回的数据,所以这里用 startActivityForResult()方法启动我们的***项视图 //参数一:我们要跳转到哪里 //参数二:回传码 this.startActivityForResult(intent, 0); }else if (item.getItemId() == R.id.menu_quit) { //当我们点击Quit菜单退出应用程序 finish(); } return true; } //此方法用来 接收我们上一个Activity 也就是我们的***项视图 返回的数据,因为我们可能会修改数据 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); setOptionText(); } //这个方法就是用来设置我们 MainActivity 上的TextView的值(就是我们***项的值) private void setOptionText(){ /*这个方法比较有意思了 * ***个参数:用来指定我们存储我们***项值的文件的名称 * 格式就是 包名_preferences,大家可以看到我的包名就是xiaohang.zhimeng * 这里如果你不按照这个格式写 比如你不写你当前包名 写成别的,也会生成 当前包名_preferences 这个文件 写或不写它就在那里 * 第二个参数:打开模式 * */ SharedPreferences prefs = getSharedPreferences("xiaohang.zhimeng_preferences", 0); //这个方法大家去看文档,否则我会越写越乱 String option = prefs.getString(this.getResources().getString(R.string.selected_flight_sort_option), this.getResources().getString(R.string.flight_sort_option_default_value)); //得到我们***项 所有选项的文本 String[] optionText = this.getResources().getStringArray(R.array.flight_sort_options); //设置我们 TextView要显示的值 tv.setText("option value is " + option + "(" + optionText[Integer.parseInt(option)] + ")"); } }
如果大家对这里比较陌生,比如 SharedPreferences 是什么东西,可以参考这两篇文章。
http://byandby.iteye.com/blog/837601
http://byandby.iteye.com/blog/833292
在下边就是我们的AndroidManifest.xml文件了,倒也没啥特别的。
Xml代码
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="xiaohang.zhimeng" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".FlightPreferenceActivity" android:label="@string/prefTitle"> <intent-filter> <action android:name="xiaohang.zhimeng.intent.action.FlightPreferences" /> <category android:name="android.intent.category.PREFERENCE" /> </intent-filter> </activity> </application> </manifest>
OK,当我们完成了上边的所有运行应用程序,首先会看到一个简单的文本消息,显示“option value is 1(# of Stops)”。单击Menu按钮,然后在点击Settings,就会打开我们的***项视图FlightPreferenceActivity,然后我们更改***项的值,然后再点击back按钮就会看到我们修改后的值了。
大家可能会问,那Android把我们修改后的数据存储在哪里了呢?前面已经提到Android framework还会负责持久化***项。例如,当用户选择一个排序选项时,Android会选择存储在应用程序 /data 目录下的一个XML 文件中,见下图。
实际的文件路径为 /data/data/[PACKAGE_NAME]/shared_prefs/[PACKAGE_NAME]_preferences.xml。我们需要 看看这个文件里边到底存了些什么? 导出这个文件就可以看到了。哦 不对,不用这样 太麻烦了, 我们 去 shell 里边 用 cat 读一下就行了,见下图。
一看便知,是以键值对的方式存取。
上述就是小编为大家分享的如何理解Android首选项框架ListPreference了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。