探索首選項框架
在深刻探討Android的首選項框架以前,首先構想一個須要使用首選項的場景,而後分析如何實現這一場景。假設你正在編寫一個應用程序,它提供了一個搜 索飛機航班的工具。並且,假設該應用程序的默認設置是根據機票價格由低到高的順序顯示航班,但用戶能夠將首選項設置爲始終根據最少停站數或特定航線來航 班。若是實現這一場景?
ListPreference
顯然,必須爲用戶提供UI 來查看排序選項列表。該列表將包含每一個選項的單選按鈕,並且默認(或當前)選項應該被預先選中。要使用Android首選項框架解決此問題,所作的工做非 常之少。首先,建立首選項XML文件來描述首選項,而後使用預先構建的活動類,該類知道如何顯示和持久化首選項,下面是咱們的首選項 XML 文件flightoptions.xml 。
android
<?xml version="1.0" encoding="utf-8"?> 數據庫
<PreferenceScreen 編程
xmlns:android="http://schemas.android.com/apk/res/android" app
android:key="flight_option_preference" 框架
android:title="@string/prefTitle" ide
android:summary="@string/prefSummary"> 工具
<ListPreference 佈局
android:key="@string/selected_flight_sort_option" ui
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 代碼以下:
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 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 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 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 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類
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 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 讀一下就好了,見下圖。
一看便知,是以鍵值對的方式存取,就寫到這裏了,明天寫 CheckBoxPreference,最近IO大會很火熱啊,據說 Google 還要讓Android控制 家電,懼怕中。。。
源碼已上傳
Preference_Demo.rar (48.1 KB)
下載次數: 415