android學習日記——PreferenceActivity詳解

PreferenceActivity詳解

何爲PreferenceActivity

以下爲官方解釋:

This is the base class for anactivity to show a hierarchy of preferences to the user. 

個人理解:這是一個特別針對Android開發中經常用到的選項設置而封裝的Activity。

 

幾點注意的:

l  官方推薦跟PreferenceFragment結合使用,繼承該類的子類重寫onBuildHeaders(List)方法來填充首選項的值,以header + PreferenceFragment的方式取代以前直接顯示選項表的做法。

l  該Activity應包含一個或多個選項頭(header),且每一個選項頭對應一個PreferenceFragment,但與其關聯的佈局顯示可以完全不同

l  針對不同尺寸,頁面顯示效果不同。針對大屏幕,同一頁面中選項頭與PreferenceFragment同時顯示;針對小屏幕,同一頁面中,只有選項頭以列表的形式顯示,PreferenceFragment以下一級頁面顯示。

l  依據官方推薦的辦法,在一個Header的情況下小屏幕設備上有多頁面的效果,顯得有點多餘,如果想直接就顯示選項,有兩種辦法:

1.        直接在PreferenceActivity調用addPreferencesFromResource方法

2.        Android 3.0 之後推薦使用PreferenceFragment。具體辦法爲在Activity頁面中定義一個PreferenceFragment並在重寫的onCreate辦法中加載其佈局文件,在該Activity頁面中的onCreate辦法添加PreferenceFragment。(PS:核心代碼:getFragmentManager().beginTransaction().replace(android.R.id.content,new XXXFragment()).commit();

 

 

例子

官方例子主要文件:

l  Java源文件PreferenceWithHeaders;

l  首選項xml佈局文件 preference_headers;

l  次級選項PreferenceFragment的xml佈局文件fragmented_preferences;fragmented_preferences_inner等等。

簡單說下官方例子的編程思路:

1.        新建一個X.java文件繼承PreferenceActivity,重寫onBuildHeaders(List<Header>target),在裏面調用loadHeadersFromResource (int resid,List<PreferenceActivity.Header> target)辦法填充首選項列表

2.        新建一個首選項列表的佈局文件preference_headers .xml

3.        在x.java類里加入與佈局文件中相應headers關聯的PreferenceFragment子類爲內部類,在子類裏重寫onCreate方法,加載此PreferenceFragment的佈局文件

4.        新建一個與剛PreferenceFragment相關聯的佈局文件

5.        重複3,4步驟直到完成所需

 

擴展

l  自定義Preference(引用,不詳)

有5點需要注意的,官方文檔如下顯示

·        Specify the user interface that appears when the userselects the settings.

·        Save the setting's value when appropriate.

·        Initialize the Preference with thecurrent (or default) value when it comes into view.

·        Provide the default value when requested by the system.

·        If the Preference providesits own UI (such as a dialog), save and restore the state to handle lifecyclechanges (such as when the user rotates the screen).

·        The following sections describehow to accomplish each of these tasks.

·        Specifying the user interface

·         

·        If you directly extendthe Preference class,you need to implement onClick() todefine the action that occurs when the user selects the item. However, mostcustom settings extend DialogPreference toshow a dialog, which simplifies the procedure. When you extend DialogPreference,you must callsetDialogLayoutResourcs() duringin the class constructor to specify the layout for the dialog.

·        For example, here's theconstructor for a custom DialogPreference thatdeclares the layout and specifies the text for the default positive andnegative dialog buttons:

·    public class NumberPickerPreference extends DialogPreference {
·        public NumberPickerPreference(Context context, AttributeSet attrs) {
·            super(context, attrs);
·            
·            setDialogLayoutResource(R.layout.numberpicker_dialog);
·            setPositiveButtonText(android.R.string.ok);
·            setNegativeButtonText(android.R.string.cancel);
·            
·            setDialogIcon(null);
·        }
·        ...
·    }

·        Saving the setting's value

·        You can save a value for thesetting at any time by calling one of the Preference class's persist*() methods,such as persistInt() ifthe setting's value is an integer or persistBoolean() tosave a boolean.

·        Note: Each Preference cansave only one data type, so you must use the persist*() methodappropriate for the data type used by your custom Preference.

·        When you choose to persist thesetting can depend on which Preference classyou extend. If you extendDialogPreference,then you should persist the value only when the dialog closes due to a positiveresult (the user selects the "OK" button).

·        When a DialogPreference closes,the system calls the onDialogClosed() method.The method includes a boolean argument that specifies whether the user resultis "positive"—if the value is true, thenthe user selected the positive button and you should save the new value. Forexample:

·    @Override
·    protected void onDialogClosed(boolean positiveResult) {
·        // When the user selects "OK", persist the new value
·        if (positiveResult) {
·            persistInt(mNewValue);
·        }
·    }

·        Initializing the current value

·        When the system adds your Preference tothe screen, it calls onSetInitialValue() tonotify you whether the setting has a persisted value. If there is no persistedvalue, this call provides you the default value.

·        The onSetInitialValue() methodpasses a boolean, restorePersistedValue, toindicate whether a value has already been persisted for the setting. If itis true,then you should retrieve the persisted value by calling one of the Preference class's getPersisted*() methods,such as getPersistedInt() foran integer value. You'll usually want to retrieve the persisted value so youcan properly update the UI to reflect the previously saved value.

·        If restorePersistedValue is false,then you should use the default value that is passed in the second argument.

·    @Override
·    protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
·        if (restorePersistedValue) {
·            // Restore existing state
·            mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
·        } else {
·            // Set default state from the XML attribute
·            mCurrentValue = (Integer) defaultValue;
·            persistInt(mCurrentValue);
·        }
·    }

·        Providing a default value

·        If the instance of your Preference classspecifies a default value (with the android:defaultValue attribute),then the system calls onGetDefaultValue() whenit instantiates the object in order to retrieve the value. You must implementthis method in order for the system to save the default value in the SharedPreferences.For example:

·    @Override
·    protected Object onGetDefaultValue(TypedArray a, int index) {
·        return a.getInteger(index, DEFAULT_VALUE);
·    }

·        Saving and restoring the Preference's state

·        Just like a View ina layout, your Preference subclassis responsible for saving and restoring its state in case the activity orfragment is restarted (such as when the user rotates the screen). To properlysave and restore the state of your Preference class,you must implement the lifecycle callback methods onSaveInstanceState()and onRestoreInstanceState().

·        The state of your Preference isdefined by an object that implements the Parcelable interface.The Android framework provides such an object for you as a starting point todefine your state object: thePreference.BaseSavedState class.

·    private static class SavedState extends BaseSavedState {
·        // Member that holds the setting's value
·        // Change this data type to match the type saved by your Preference
·        int value;
·     
·        public SavedState(Parcelable superState) {
·            super(superState);
·        }
·     
·        public SavedState(Parcel source) {
·            super(source);
·            // Get the current preference's value
·            value = source.readInt();  // Change this to read the appropriate data type
·        }
·     
·        @Override
·        public void writeToParcel(Parcel dest, int flags) {
·            super.writeToParcel(dest, flags);
·            // Write the preference's value
·            dest.writeInt(value);  // Change this to write the appropriate data type
·        }
·     
·        // Standard creator object using an instance of this class
·        public static final Parcelable.Creator<SavedState> CREATOR =
·                new Parcelable.Creator<SavedState>() {
·     
·            public SavedState createFromParcel(Parcel in) {
·                return new SavedState(in);
·            }
·     
·            public SavedState[] newArray(int size) {
·                return new SavedState[size];
·            }
·        };
·    }

·        With the above implementationof Preference.BaseSavedState addedto your app (usually as a subclass of your Preference subclass),you then need to implement the onSaveInstanceState() andonRestoreInstanceState() methodsfor your Preference subclass.

·        For example:

·    @Override
·    protected Parcelable onSaveInstanceState() {
·        final Parcelable superState = super.onSaveInstanceState();
·        // Check whether this Preference is persistent (continually saved)
·        if (isPersistent()) {
·            // No need to save instance state since it's persistent, use superclass state
·            return superState;
·        }
·     
·        // Create instance of custom BaseSavedState
·        final SavedState myState = new SavedState(superState);
·        // Set the state's value with the class member that holds current setting value
·        myState.value = mNewValue;
·        return myState;
·    }
·     
·    @Override
·    protected void onRestoreInstanceState(Parcelable state) {
·        // Check whether we saved the state in onSaveInstanceState
·        if (state == null || !state.getClass().equals(SavedState.class)) {
·            // Didn't save the state, so call superclass
·            super.onRestoreInstanceState(state);
·            return;
·        }
·     
·        // Cast state to custom BaseSavedState and pass to superclass
·        SavedState myState = (SavedState) state;
·        super.onRestoreInstanceState(myState.getSuperState());
·        
·        // Set this Preference's widget to reflect the restored state
·        mNumberPicker.setValue(myState.value);
·    }
·    private static class SavedState extends BaseSavedState {
·        // Member that holds the setting's value
·        // Change this data type to match the type saved by your Preference
·        int value;
·     
·        public SavedState(Parcelable superState) {
·            super(superState);
·        }
·     
·        public SavedState(Parcel source) {
·            super(source);
·            // Get the current preference's value
·            value = source.readInt();  // Change this to read the appropriate data type
·        }
·     
·        @Override
·        public void writeToParcel(Parcel dest, int flags) {
·            super.writeToParcel(dest, flags);
·            // Write the preference's value
·            dest.writeInt(value);  // Change this to write the appropriate data type
·        }
·     
·        // Standard creator object using an instance of this class
·        public static final Parcelable.Creator<SavedState> CREATOR =
·                new Parcelable.Creator<SavedState>() {
·     
·            public SavedState createFromParcel(Parcel in) {
·                return new SavedState(in);
·            }
·     
·            public SavedState[] newArray(int size) {
·                return new SavedState[size];
·            }
·        };
·    }

·        With the above implementationof Preference.BaseSavedState addedto your app (usually as a subclass of your Preference subclass),you then need to implement the onSaveInstanceState() andonRestoreInstanceState() methodsfor your Preference subclass.

 

 

 

l  使用intents跳轉其他頁面:如網頁

<Preference android:title="@string/prefs_web_page">

    <intent android:action="android.intent.action.VIEW"

            android:data="http://www.example.com"/>

</Preference>

l  讀取數據

取得該頁面的SharedPreferences對象來讀取數據,如下所示

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");

l  監聽preference 變化

通過將PreferenceActivity的子類實現SharedPreference.OnSharedPreferenceChangeListener接口,實現onSharedPreferenceChanged()辦法。官方推薦重寫PreferenceActivity的暫停和重新開始的辦法,調用registerOnSharedPreferenceChangeListener()爲SharedPreferences對象註冊監聽器實現監聽,如下

protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences()
            .registerOnSharedPreferenceChangeListener(this);
}

l  引用(不詳)

從Android4.0以後,系統設置應用程序允許用戶查看他們的應用在前臺和後臺使用了多少網絡數據。用戶可以禁用每個應用在後臺使用網絡數據。爲了避免用戶禁用你的應用在後臺訪問網絡,你應該更效率的使用網絡,並且允許用戶通過你的應用的Settings來改善數據用量。

例如,你或許允許用戶控制你的應用同步數據的頻率,是否你的app只在wifi下上傳下載數據,是否在漫遊時訪問網絡等。

當你添加了必要的Preference到你的PreferenceActivity中來控制你的app的數據訪問習慣,你應該添加一個Intent filter給你的PreferenceActivity。例子:

<activityandroid:name="SettingsActivity" ... >

   <intent-filter>

      <actionandroid:name="android.intent.action.MANAGE_NETWORK_USAGE" />

      <category android:name="android.intent.category.DEFAULT"/>

   </intent-filter>

</activity>

這個Intent-filter告訴系統這個Activity是控制你的應用程序的數據用量的Activity。因此,當用戶從系統設置應用程序中查詢你的應用使用了多少數據時,一個查看”應用程序設置“的按鈕就可以加載你的PreferenceActivity,用戶也就可以改善你的應用應該如何使用數據。

 

參考:http://supershll.blog.163.com/blog/static/37070436201311931338135/

官方文檔;     




發佈了30 篇原創文章 · 獲贊 2 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章